Quartz定时任务持久化(服务重启后自动恢复)
Quartz 定时任务持久化(重启后自动恢复)声明: 本文内容由 ChatGPT 协助生成,仅作为个人学习与记录之用。
Quartz 默认使用 RAMJobStore(内存存储),服务重启后任务会丢失。
要让定时任务在重启后仍然有效,必须启用:JDBCJobStore(数据库持久化)
本文说明如何在 Spring Boot 项目中配置 Quartz 持久化,使任务存入数据库并在重启后自动恢复。
1. 启用 Quartz 持久化(application.yml)
示例配置:
spring:
quartz:
job-store-type: jdbc # 启用数据库持久化
jdbc:
initialize-schema: always # 第一次启动自动建表,之后改为 never
properties:
org.quartz.scheduler.instanceName: QuartzScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties: false
org.quartz.jobStore.tablePrefix: QRTZ_
org.quartz.threadPool.threadCount: 10注意:
[*]initialize-schema: always 只在第一次启动时用
第二次以后必须改为 never,避免自动重建表导致任务丢失。
[*]数据库需先创建好,Quartz 会自动建表(第一次)。
2. 初始化数据库(Quartz 表结构)
Quartz 内置表结构 SQL,可在 quartz-x.x.jar 中找到:
路径:
org/quartz/impl/jdbcjobstore/
根据数据库选择:
数据库SQL 文件MySQLtables_mysql_innodb.sqlPostgreSQLtables_postgres.sqlOracletables_oracle.sql执行后会生成 11 张表,例如:
[*]QRTZ_JOB_DETAILS
[*]QRTZ_TRIGGERS
[*]QRTZ_CRON_TRIGGERS
[*]QRTZ_SIMPLE_TRIGGERS
[*]QRTZ_FIRED_TRIGGERS
[*]QRTZ_SCHEDULER_STATE
[*]QRTZ_LOCKS
...
这些表记录 Job/Trigger,实现持久化。
3. 可选:为 Job 启用持久化注解(存储 JobDataMap)
如果你的 Job 需要持久化任务状态,添加:
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class MyJob implements Job {
...
}功能说明:
注解作用@PersistJobDataAfterExecution执行后的JobDataMap数据状态写回数据库@DisallowConcurrentExecution任务串行执行,避免读写冲突@DisallowConcurrentExecution 的作用
防止同一个 Job 的多个实例并发执行。
也就是说:
Quartz 会等待当前 Job 执行完,才会执行下一次触发。
为什么需要这个注解?
Quartz 默认行为是:
[*]假设你的 Job 计划每 5 秒 执行一次
[*]但你的任务实际执行时间是 10 秒
那么:
[*]Quartz 会在第 5 秒再并发启动一个 Job 实例
[*]第 10 秒再启动一个
[*]这样会导致同一个 Job 多实例并发执行
这在很多业务场景是危险的:
[*]写数据库时造成脏数据
[*]写文件导致冲突
[*]调接口重复提交
[*]修改共享变量时出并发问题
加上 @DisallowConcurrentExecution 后
Quartz 保证:
✔ 第一个任务没执行完
✔ Quartz 不会再启动第二个
✔ 任务之间严格串行执行
✔ 安全性强
@PersistJobDataAfterExecution 的作用
让你在 Job 里面修改的参数(JobDataMap)能被保存下来,下次执行还能继续用。
举个最简单的例子
你有个定时任务,每次执行想让计数器 count +1:
int count = data.getInt("count");
data.put("count", count + 1);如果 没有 @PersistJobDataAfterExecution:
[*]每次执行 count 都从 0 开始
[*]因为 Quartz 不会把你更新的值保存下来
如果 加上 @PersistJobDataAfterExecution:
[*]count 会变成 1、2、3、4...
[*]Quartz 会把更新后的值写回数据库
[*]服务重启后 count 也不会丢
只要你在 job 里对 JobDataMap 做写操作,想保存结果 → 就一定要加 @PersistJobDataAfterExecution + @DisallowConcurrentExecution。(防止并发造成的数据覆盖和丢失)
如果你只需要任务被保存,而不需要保存 JobDataMap,可以不加这两个注解。
4. 创建 Job 时必须设置 .storeDurably()
持久化 Job 的关键:
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1")
.storeDurably() // ★★★★★ 必须,Job 才会存入数据库
.build();不加 storeDurably() 的 Job 会被当成“临时 Job”,服务重启后会丢失。
Trigger 默认会持久化,不需要额外配置。
5. 服务重启后自动恢复机制
Quartz 启动时会自动从以下表中加载任务:
[*]QRTZ_JOB_DETAILS
[*]QRTZ_TRIGGERS
[*]QRTZ_CRON_TRIGGERS / QRTZ_SIMPLE_TRIGGERS
无需额外代码。
6. 如何验证持久化是否生效
[*]创建一个 Job + Trigger
[*]启动服务 → 任务执行正常
[*]查看数据库 QRTZ_ 前缀的表,是否有记录
[*]停止服务
[*]再次启动
[*]任务是否自动恢复执行
如能恢复,即持久化成功。
参考文章:
【Quartz】(一)定时框架Quartz的持久化配置: https://blog.csdn.net/Jeffhan_java/article/details/123532049
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 收藏一下 不知道什么时候能用到 鼓励转贴优秀软件安全工具和文档! 很好很强大我过来先占个楼 待编辑 感谢分享 不错,里面软件多更新就更好了 yyds。多谢分享 用心讨论,共获提升! 感谢发布原创作品,程序园因你更精彩 感谢发布原创作品,程序园因你更精彩 前排留名,哈哈哈 谢谢楼主提供! 很好很强大我过来先占个楼 待编辑 感谢分享,下载保存了,貌似很强大 不错,里面软件多更新就更好了 过来提前占个楼 分享、互助 让互联网精神温暖你我 感谢分享 热心回复! 前排留名,哈哈哈
页:
[1]
2