Quartz Java resuming a job executes it many times

后端 未结 3 1960
谎友^
谎友^ 2020-12-04 11:52

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

3条回答
  •  青春惊慌失措
    2020-12-04 12:20

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

提交回复
热议问题