当代码SimpleTriggerRunner执行到一段时间后非正常退出,我们就可以通过这个JDBCJobStoreRunner根据记录在中的现场数据恢复任务的调度。Scheduler中的所有Trigger以及JobDetail的运行信息都会保存在中,这里我们仅恢复tgroup1组中名称为trigger1_1的触发器,这可以通过所示的代码进行过滤,触发器的采用GROUP.TRIGGER_NAME的全名式。通过Scheduler#rescheduleJob(String triggerName,String groupName,Trigger newTrigger)即可重新调度关联某个Trigger的任务。
下面我们来观察一下不同时期qrtz__triggers表的数据:
1.运行代码SimpleTriggerRunner一小段时间后退出:
REPEAT_COUNT表示需要运行的总次数,而TIMES_TRIGGER表示已经运行的次数。
2.运行代码JDBCJobStoreRunner恢复trigger1_1的触发器,运行一段时间后退出,这时qrtz__triggers中的数据如下:
首先Quartz会将原REPEAT_COUNT-TIMES_TRIGGER得到新的REPEAT_COUNT,并记录已经运行的次数(重新从0开始计算)。
3.重新启动JDBCJobStoreRunner运行后,数据又将发生相应的变化:
4.继续运行直至完成所有剩余的次数,再次查询qrtz__triggers表:
这时,该表中的记录已经变空。
得注意的是,如果你使用JDBC保存任务调度数据时,当你运行代码SimpleTriggerRunner然后退出,当再次希望运行SimpleTriggerRunner时,系统将抛出JobDetail重名的异常:Unable to store Job with name: 'job1_1' and group: 'jGroup1', because one already exists with this identification.
因为每次调用Scheduler#scheduleJob()时,Quartz都会将JobDetail和Trigger的信息保存到中,如果数据表中已经同名的JobDetail或Trigger,异常就产生了。
本文使用quartz 1.6版本,我们发现当后台使用MySql时,数据保存不成功,该错误是Quartz的一个Bug,相信会在高版本中得到修复。因为HSQLDB不支持SELECT * FROM TABLE_NAME FOR UPDATE的语法,所以不能使用HSQLDB。
附录
·org.quartz.scheduler.instanceName
每个 Scheduler 必须给定一个名称来标识。当在同一个程序中有多个实例时,这个名称作为客户代码识别是哪个 Scheduler 而用。假如你用到了集群特性,你就必须为集群中的每一个实例使用相同的名称,以使它们成为“逻辑上” 是同一个 Scheduler 。
·org.quartz.scheduler.instanceId
每个 Quartz Scheduler 必须指定一个唯一的 ID。这个可以是任何字符串,只要对于所有的 Scheduler 是唯一的。如果你想要自动生成的 ID,那你可以使用AUTO作为instanceId。从版本 1.5.1 开始,你能够定制如何自动生成实例 ID。见instanceIDGenerator.class属性,会在接下来讲到。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-44264-8.html
你是老百姓
人均GDP和收入看起来你好富啊