勿以恶小而为之,勿以善小而不为--------------------------刘备
劝诸君,多行善事积福报,莫作恶
上一章简单介绍了 SSM整合Quartz(八) ,如果没有看过,请观看上一章
本文参考了 阿飞云前辈的文章: 精进 Quartz—Quartz大致介绍(一)
一. Quartz 持久化之前的准备
一.一 为什么要持久化?
以前写的 Demo,包括 SSM整合 Quartz 框架,都不是持久化的,都是存储在内存里面的。 当程序突然被中断时,如断电,内存超出时,很有可能造成任务的丢失。 可以将调度信息存储到数据库里面,进行持久化,当程序被中断后,再次启动,仍然会保留中断之前的数据,继续执行,而并不是重新开始。
一.二 两种存储类型
Quartz 框架提供了两种任务存储的类型, 分别为 RAMJobStore 和 JobStoreTX
类型 | 优点 | 缺点 |
RAMJobStore | 存储在内存里,配置简单,运行速度快 | 当程序停止时,调度信息会丢失。 可以存储的 JobDetail和 Trigger 有数量限制 |
JobStoreTX | 存储在数据库里面,当程序中断时,调度信息不会丢失 支持事务,支持集群。 再次启动时,会恢复因程序关闭,重启 而错过的任务。 | 运行速度较慢, 具体与连接数据库的速度有关 |
一.三 创建 持久化表
一.三.一 创建持久化表语句
放置到 老蝴蝶本地 quartz 数据库里面。
运行成功之后
共11个表,表名均以 qrtz_ 为前缀。
一.三.二 表关系
说明,从阿飞云前辈的博客里面复制的。
一.三.三 持久化表解释
说明,从阿飞云前辈的博客里面复制的。
表名 | 表作用 |
qrtz_blob_triggers | 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型, JobStore 并不知道如何存储实例的时候) |
qrtz_calendars | 以Blob类型存储Quartz的Calendar日历信息, quartz可配置一个日历来指定一个时间范围 |
qrtz_cron_triggers | 存储Cron Trigger,包括Cron表达式和时区信息。 |
qrtz_fired_triggers | 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息 |
qrtz_job_details | 存储每一个已配置的Job的详细信息 |
qrtz_locks | 存储程序的非观锁的信息(假如使用了悲观锁) |
qrtz_paused_trigger_grps | 存储已暂停的Trigger组的信息 |
qrtz_scheduler_state | 存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中) |
qrtz_simple_triggers | 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数 |
qrtz_simprop_triggers | 未知 |
qrtz_triggers | 存储已配置的 Trigger 的信息 |
一般项目中配置的都是 Cron 触发器, 需要记录 qrtz_cron_triggers 和 qrtz_job_details, qrtz_triggers 三个常用表。
二. Quartz 框架的持久化
二.一 复制配置信息 quartz.properties
Quartz 框架在运行时,需要一个配置文件 quartz.properties, 里面放置基本的配置信息。
该文件位于 quartz.jar 下面的 org.quartz 包下。
将该文件复制到 src/main/resource 目录下
我们可以修改 resource目录下的 quartz.properties 属性文件内容 进行自定义配置。
org.quartz.jobStore.class,指的是 Quartz 的存储类型, 默认是 RAMJobStore, 存储在内存里面。
关于 quartz.properties 配置文件的信息,大家可以看 W3CSchool 关于 Quartz 部分的文章。
二.二 将类型转换成 JobStoreTX
JobStoreTX 全称是: org.quartz.impl.jdbcjobstore.JobStoreTX
二.三 配置驱动代理
StdJDBCDelegate 为标准的jdbc。
二.四 配置数据库表前缀和数据源
其中, yjlDB 是数据源名称, 可以任意起一个, 但要与下面的 dataSource.Xxx 保持一致。
注意,这个时候,只是简单的 JavaSE 配置,并没有与 Spring进行整合,
所以数据库直接写在 quartz.properties 属性文件里面。
当与Spring 进行整合之后,直接拿 applicationContext-dao.xml 里面的数据源 dataSource 即可。
当配置 org.quartz.dataSource.yjlDB.maxConnection:10 时会报错,说没有 setMaxConnection() 方法。
这儿就不配置 org.quartz.dataSource.yjlDB.maxConnection 的值了。
二.五 最终 quartz.properties 配置文件内容
三. 持久化演示
三.一 编写任务 MyJobStoreTX
三.二 编写主程序 MyJobStoreTxDemo
三.三 运行程序,看控制台打印输出
每隔两秒,运行一次。
查看数据库的 qrtz_cron_triggers 表内容:
查看数据库的 qrtz_job_details 表内容:
查看数据库的 qrtz_triggers 表内容:
将 JobDetail, Trigger 的内容放置到了数据库里面,进行了持久性的保存。
三.四 关闭程序后,再次运行
再次运行
Exception in thread “main” org.quartz.ObjectAlreadyExistsException:
Unable to store Job : ‘groupTX1.jobTX1’, because one already exists with this identification.
说已经存在了, 即 JobDetail的 组名称.job名称, 两个唯一确定一个JobDetail 任务对象。
与平常项目中的操作一样,在创建之前,先进行验证, 如果存在了,就执行以前的那个,如果不存在,就创建。
三.五 创建前验证是否存在的主程序 MyJobStoreTxDemo
三.六 重新启动,查看控制台输出
正常启动作业任务。
四. Spring 配置 Quartz 持久化
与 Spring 配置 Quartz 差不多,仍然使用以前的例子。
注意,这个时候,将 quartz.properties 的数据源配置暂时移除, 数据源的配置交给 Spring 管理了。
将 MyJob.java 的 输出语句改变一下,更好的区分。
四.一 配置静态的任务
每2s 触发一次。
四.二 重启服务器,运行
正常的启动。
查看数据库, qrtz_cron_triggers 内容
其他两个表也同样有数据。
持久化成功。
四.三 移除 JobDetail 和 Trigger的配置
因为将 JobDetail 和 Trigger的信息,已经持久化到数据库里面了, 那么就可以将它的配置进行移除了(通常是不移除的,
这儿只是演示一下持久化)。
只保留 Scheduler 的配置
这个时候,重启服务器,
仍然可以正常的运行。
通过数据库持久化,可以做定时任务管理系统。
五. Quartz 持久化的扩展
将 JobDetail,Trigger 存储到数据库里面,就可以完成持久化, 在项目运行的过程中,如果将合法的数据,
插入到对应的数据库表里面,是否就可以创建任务呢, 作一个任务管理系统的模块呢? 是可以的。
Quartz 支持动态的添加任务。
五.一 编写动态任务 MyJob2
类完整路径为: com.yjl.job.MyJob2
五.二 构建JobAndTrigge 的实体Bean JobAndTrigger
创建一个 JobAndTrigger的Bean, 里面封装一些 Job和Trigger的对象信息, 这些对象信息是前端传递过来的。
五.三 编写 Action QuartzAction
五.四 applicationContext-job.xml 配置
与 四.三 移除后的配置一致, 不重复复制了。
五.五 编写前端页面 index.jsp
直接放置到 index.jsp 页面里面了, 引入 bootstrap 来美化样式。
构建一个简单的 Cron 触发器。
五.六 重启服务器验证
输入网址: http://localhost:8080/Quartz_Persistence
填写相应的信息:
在点击之前,看一下控制台的任务执行:
全部都是 Spring 的。
点击 添加任务按钮,
查看一下控制台:
页面跳转
数据库信息 qrtz_cron_triggers 内容查看
关闭服务器后,重新开启
可以动态地进行添加任务,当然,也可以进行移除任务,挂起任务,修改任务的触发cron表达等。
老蝴蝶这儿就不做过多的讲解了。
本章节代码链接为:
谢谢您的观看!!!