Quartz Java重新开始工作多次 [英] Quartz Java resuming a job excecutes it many times

查看:137
本文介绍了Quartz Java重新开始工作多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的应用程序,我创建作业并使用CronTriggers安排它们。每个作业只有一个触发器,作业名称和触发器名称都相同。没有工作共享触发器。

For my application i create jobs and schedule them with CronTriggers. Each job has only one trigger and both the job name and the trigger names are the same. No jobs share a trigger.

现在当我创建一个类似0/1 * * * *?的cron触发器时,它指示每秒执行的工作,它运作得很好。

Now when i create a cron trigger like this "0/1 * * * * ?" which instructs the job to execute every second, it works just fine.

当我第一次暂停工作时,问题就出现了:

The problem rises when i first pause the job by calling :

scheduler.pauseJob(jobName, jobGroup);

然后在让我们说50秒后恢复工作:

and then resuming the job after let's say 50 seconds with :

scheduler.resumeJob(jobName, jobGroup);

我看到的是,在这50秒内,作业没有按要求执行。但是,当我恢复工作的那一刻,我同时看到50份执行工作!!!

What i see is that for these 50 seconds the job did not execute as requested. But the moment i resume the job i see 50 executions of the job at the same time!!!

我认为这是由于失火指令的默认设置但即使在创建时将触发器的失火指示设置为:

I thought that this was due to the default setting for the misfire instruction but even after setting the trigger's misfire instruciton upon creation to this :

trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);

同样的事情发生了。任何人都可以建议一种解决方法吗?

The same thing happens. Can anyone suggest a way to fix this?

推荐答案

CronTrigger 有效通过记住 nextFireTime 。创建触发器后,初始化 nextFireTime 。每次触发作业时 nextFireTime 都会更新。由于暂停时未触发作业 nextFireTime 仍为旧。因此,在您恢复作业后,触发器将返回每个旧触发时间。

The CronTrigger works by remembering the nextFireTime. After creating the trigger the nextFireTime is initialized. Every time the job is triggered nextFireTime is updated. Since the job is not triggered when paused nextFireTime remains "old". So after you resume the job the trigger will return every old trigger time.

问题是,触发器不知道它正在暂停。为了解决这个问题,有这种失火处理。恢复作业后,将调用触发器的 updateAfterMisfire()方法,该方法更正 nextFireTime 。但是,如果 nextFireTime 与现在之间的差异小于 misfireThreshold 。然后永远不会调用该方法。此阈值的默认值为60,000。因此,如果你的暂停时间超过60秒,一切都会好的。

The problem is, the trigger doesn't know it is being paused. To overcome this there is this misfire handling. After resuming the jobs the trigger's updateAfterMisfire() method will be invoked which corrects the nextFireTime. But not if the difference between nextFireTime and now is smaller than the misfireThreshold. Then the method is never called. This threshold's default value is 60,000. Thus if your pause period would be longer than 60s everything would be fine.

因为你有问题我认为不是。 ;)
要解决这个问题,你可以修改阈值或使用一个简单的包装器 CronTrigger

Since you have problems I assume it is not. ;) To workaround this you can modify the threshold or use a simple wrapper around CronTrigger:

public class PauseAwareCronTrigger extends CronTrigger {
    // constructors you need go here

    @Override
    public Date getNextFireTime() {
        Date nextFireTime = super.getNextFireTime();
        if (nextFireTime.getTime() < System.currentTimeMillis()) {
            // next fire time after now
            nextFireTime = super.getFireTimeAfter(null);
            super.setNextFireTime(nextFireTime);
        }
        return nextFireTime;
    }
}

这篇关于Quartz Java重新开始工作多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆