Quartz Java resuming a job excecutes it many times

二次信任 提交于 2019-11-27 17:32:28
Eduard Wirch

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.

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.

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;
    }
}

If you pause the job, the trigger will continue to fire, but the executions will queue up until the job is resumed. This isn't a misfiring trigger, so that setting will have no effect.

What you want to do, I think, is programmatically disable or remove the cron trigger, rather than pausing the job. When you want to resume, then re-add the trigger.

Since 1.6.5 at least (the earliest version of quartz at my fingertips), the scheduler has a pauseTrigger method that takes the name/group as parameters. This means you don't have to have a sub-class of every trigger type you use, nor do you have to do funky deletion/insertion tricks.

Both of these are important to me because 1) our database has a strict no-deletes policy and 2) the custom datastore I use doesn't support trigger sub-classes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!