Original address: Http://stackoverflow.com/questions/1933676/quartz-java-resuming-a-job-excecutes-it-many-times
Question:
For my application I create jobs and schedule them with crontriggers. Each job have only one trigger and both the job name and the trigger names is the same. No jobs share a trigger.
Now if I create a cron trigger like this "0/1 * * * *?" which instructs the job to execute every second, it wo Rks just fine.
The problem rises when I first pause the job by calling:
scheduler.pauseJob(jobName, jobGroup);
And then resuming the job after let's say seconds with:
scheduler.resumeJob(jobName, jobGroup);
What am I see is so for these seconds the job does not execute as requested. But the moment I resume the job I see executions of the job at the same time!!!
I thought that this is due to the default setting for the misfire instruction if even after setting the trigger ' s Misfir e Instruciton upon creation to this:
trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
The same thing happens. Can anyone suggest a to fix this?
Answer
The CronTrigger
works by remembering nextFireTime
. After creating the trigger, the is nextFireTime
initialized. Every time the job is triggered is nextFireTime
updated. Since the job is no triggered when paused nextFireTime
remains ' old '. So after you resume the job the trigger would return every old trigger time.
The problem is, the trigger doesn ' t know it's being paused. To overcome this there are this misfire handling. After resuming the jobs the trigger ' s updateAfterMisfire()
method would be invoked which corrects the nextFireTime
. But not if the difference between and are now nextFireTime
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 is fine.
Since you are problems I assume it is not. ;) To workaround this 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 resuming a job excecutes it many times--go