quartz动态设置时候一些坑
1. 默认设置的quartz ,
1. 在新建后会立即执行;
2. 在调用恢复方法时候,会立即执行(之前错过所有的次数,现在执行N次)
首先第一个问题很好处理,在创建的时候加上withMisfireHandlingInstructionDoNothing方法即可。
第二个问题,查了很多资料没有解决方法。找源码加上调试最后发现,和misfireThreshold这个配置有关。
我当时设置的是1分钟时间,而我设置的定时任务是每10秒执行一次,我暂停时间如果超过一分钟时间上就不在执行了。
如果我暂停时间没有超过一分钟,那么他就会把这段时间内漏执行的,在这个时间全部执行。
处理:
1.
public static void createScheduleJob(Scheduler scheduler, MdJobManage job) {
try {
// 构建jbo信息、表达式调度构建器(新建和修改信息 不做执行操作)、 触发器、
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>)Class.forName(job.getJobClassName()))
.withIdentity(job.getJobName())
.withDescription(job.getDescription())
.build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()).
withMisfireHandlingInstructionDoNothing(); // 新建后 不立即执行
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(job.getJobName())
.withDescription(job.getDescription())
.withSchedule(scheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(JOB_PARAM_KEY, job);
scheduler.scheduleJob(jobDetail, trigger);
// 暂停任务
if (job.getState() == 1) {
pauseJob(scheduler, job.getJobName());
}
} catch (SchedulerException | ClassNotFoundException e) {
log.error(e.getMessage());
}
}
原因:看了源码,
其他:
CronTrigger
withMisfireHandlingInstructionDoNothing
——不触发立即执行
——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期后
——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行
withMisfireHandlingInstructionFireAndProceed
——以当前时间为触发频率立刻触发一次执行
——然后按照Cron频率依次执行
SimpleTrigger
withMisfireHandlingInstructionFireNow
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期
——当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率
——共执行RepeatCount+1次
withMisfireHandlingInstructionNextWithExistingCount
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
withMisfireHandlingInstructionNowWithExistingCount
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
withMisfireHandlingInstructionNextWithRemainingCount
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
withMisfireHandlingInstructionNowWithRemainingCount
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
——此指令导致trigger忘记原始设置的starttime和repeat-count
——触发器的repeat-count将被设置为剩余的次数
——这样会导致后面无法获得原始设定的starttime和repeat-count值
删除多余的qrtz_ 表中的数据
DELETE from qrtz_cron_triggers where TRIGGER_NAME = 'personTimeSpaceTaskTrigger';
DELETE from qrtz_triggers where TRIGGER_NAME = 'personTimeSpaceTaskTrigger';
DELETE from qrtz_job_details where JOB_NAME = 'personTimeSpaceTask';
DELETE from qrtz_fired_triggers where TRIGGER_NAME= 'personTimeSpaceTaskTrigger';