更新现有的JobDataMap

23

我有一个已经被调度的Quartz任务。 我想更新与其关联的JobDataMap。如果我使用JobDataMap jobDataMap = scheduler.getJobDetail(....).getJobDataMap()获取一个JobDataMap,那么这个Map是"实时的"吗?也就是说,如果我更改了它,它会在调度程序中持久化吗?如果不是,我应该如何持久化它?

3个回答

36

在Quartz 2.0版本中,StatefulJob已经被弃用。为了持久化任务数据映射,请在作业类上使用@PersistJobDataAfterExecution注解,通常与@DisallowConcurrentExecution一起使用。


但是在哪张表中可以找到JobDataMap信息呢?我已经检查了所有的表格,但是没有发现它们。 - Sangram Anand
这是 QRTZ_JOB_DETAILS 表中的 Job_data 列吗? - Sangram Anand
我不知道,我还没有配置作业的数据库持久化。 - Bozho
是的,信息可以在 QRTZ_JOB_DETAILS 表中找到。 - iec2011007
棘手的部分是在作业类中编写PersistJobDataAfterExecution和DisallowConcurrentExecution两个注释。 - Antonio Martin

18

我遇到了类似的问题:我有一个每秒触发一次的定时器,会启动一个有状态的作业,并在作业的数据映射中操作队列。每次作业触发时,它会从队列中轮询并对轮询到的元素执行一些操作。随着每个作业的执行,队列中的元素会减少一个(队列会在作业内部正确更新)。当队列为空时,该作业会取消自己的计划。

我想要能够在进行中的作业/触发器上外部更新参数列表,以提供更多参数到队列中。然而,仅检索数据映射并更新队列是不够的(下一次执行显示队列未更新)。问题在于Quartz只在执行后更新作业实例的作业数据映射。

以下是我找到的解决方案:

JobDetail jobDetail = scheduler.getJobDetail("myJob", "myGroup");
jobDetail.getJobDataMap.put("jobQueue", updatedQueue);
scheduler.addJob(jobDetail, true);

最后一行指示Quartz使用您提供的作业替换存储的作业。 下次作业触发时,它将看到更新后的队列。


最新版本的Quartz(2.6.10?)似乎存在问题。 - Nigel Sheridan-Smith
抱歉 - 这是2.1.7版本...之前在2.1.6上运行正常 - Nigel Sheridan-Smith

7
请参考http://www.quartz-scheduler.org/docs/tutorial/TutorialLesson03.html:
一个 Job 实例可以被定义为“有状态”或“无状态”。无状态的 job 仅在添加到调度器时将其 JobDataMap 存储。这意味着在作业执行期间对作业数据映射内容所做的任何更改都将丢失,并且下次执行作业时作业将看不到这些更改。
相反,有状态的作业在每次执行后都会重新存储其 JobDataMap。
通过使作业实现 StatefulJob 接口而不是 Job 接口,您可以将作业标记为有状态。

5
如果我想要在执行之外更新一个作业,比如通过 JMX,该怎么办? - Simon Gibbs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接