首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

spring调整quartz并持久化

2013-04-09 
spring整合quartz并持久化?这中方式配置简单,但是存在问题1.定时任务信息都报错在内存中,服务器重启会丢失

spring整合quartz并持久化

?这中方式配置简单,但是存在问题

1.定时任务信息都报错在内存中,服务器重启会丢失信息

2.每个定时任务都是一串配置,定时任务多了不好管理

3.任务时间修改后要重新发布项目

?

二.quartz持久化(quartz1.6,最新版本的quartz稍有变动)

?

研究了一下quartz的相关文档,quartz本身就提供将任务和触发器持久化到数据库中的功能

详见<Quartz-Job-Scheduling-Framework>一书

要实现很简单:

?1.安装 Quartz 数据库表
Quartz 包括了所有被支持的数据库平台的 SQL 脚本。你能在 <quartz_home>/docs/dbTables 目录下找到那些 SQL 脚本,这里的 <quartz_home> 是解压 Quartz 分发包后的目录。
2.配置 JobStoreTX

要告诉 Quartz 运行环境你想使用一个别的 JobStore 而不是默认的 RAMJobStore,你必须配置几个属性。配置它们的顺序无关紧要,只要保证在第一次运行程序之前都做了设置。

在你的classpath下加入一个配置文件quartz.properties参数如下:

?

表 6.3. 可用于设置 JobStoreTX 的配置属性
属性默认值org.quartz.jobStore.driverDelegateClass?描述:能理解不同数据库系统中某一特定方言的驱动代理org.quartz.jobStore.dataSource?描述:用于 quartz.properties 中数据源的名称org.quartz.jobStore.tablePrefixQRTZ_描述:指定用于 Scheduler 的一套数据库表名的前缀。假如有不同的前缀,Scheduler 就能在同一数据库中使用不同的表。org.quartz.jobStore.userPropertiesFalse描述:"use properties" 标记指示着持久性 JobStore 所有在 JobDataMap 中的值都是字符串,因此能以 名-值 对的形式存储,而不用让更复杂的对象以序列化的形式存入 BLOB 列中。这样会更方便,因为让你避免了发生于序列化你的非字符串的类到 BLOB 时的有关类版本的问题。org.quartz.jobStore.misfireThreshold60000描述:在 Trigger 被认为是错过触发之前,Scheduler 还容许 Trigger 通过它的下次触发时间的毫秒数(译者注:据原文翻译,真的不好理解,实际效果可参看:http://www.blogjava.net/Unmi/archive/2007/10/23/153413.html?我在评论中的实验)。默认值(假如你未在配置中存在这一属性条目) 是 60000(60 秒)。这个不仅限于 JDBC-JobStore;它也可作为 RAMJobStore 的参数org.quartz.jobStore.isClusteredFalse描述:设置为 true 打开集群特性。如果你有多个 Quartz 实例在用同一套数据库时,这个属性就必须设置为 true。org.quartz.jobStore.clusterCheckinInterval15000描述:设置一个频度(毫秒),用于实例报告给集群中的其他实例。这会影响到侦测失败实例的敏捷度。它只用于设置了 isClustered 为 true 的时候。org.quartz.jobStore.maxMisfiresToHandleAtATime20描述:这是 JobStore 能处理的错过触发的 Trigger 的最大数量。处理太多(超过两打) 很快会导致数据库表被锁定够长的时间,这样就妨碍了触发别的(还未错过触发) trigger 执行的性能。org.quartz.jobStore.dontSetAutoCommitFalseFalse描述:设置这个参数为 true 会告诉 Quartz 从数据源获取的连接后不要调用它的 setAutoCommit(false) 方法。这在少些情况下是有帮助的,比如假如你有这样一个驱动,它会抱怨本来就是关闭的又来调用这个方法。这个属性默认值是 false,因为大多数的驱动都要求调用 setAutoCommit(false)。org.quartz.jobStore.selectWithLockSQLSELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE描述:这必须是一个从 LOCKS 表查询一行并对这行记录加锁的 SQL 语句。假如未设置,默认值就是 SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE,这能在大部分数据库上工作。{0} 会在运行期间被前面你配置的 TABLE_PREFIX 所替换。org.quartz.jobStore.txIsolationLevelSerializableFalse描述:值为 true 时告知 Quartz(当使用 JobStoreTX 或 CMT) 调用 JDBC 连接的 setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE) 方法。这有助于阻止某些数据库在高负载和长时间事物时锁的超时。

示例,使用的是sqlserver数据库:

?

?

之后将

注入到所需要的service中即可.

?

其中

?为注入的数据源,

如果使用这种方式那配置文件中的相关配置要注释掉.

?

或者将配置文件中信息写入到spring配置文件中:

?

?

?

期间遇到的问题留作记录:

1.持久化时遇到报字段不正确或表不存在的问题

原因: 我使用的是quartz 2.1建的表而jar包是1.6的

解决方法: 将建表语句和jar包统一版本即可

?

2.报dataSource name不存在的问题

原因: quartz.properties中的 org.quartz.jobStore.dataSource = myDS?

忘记打开或者与数据源配置没有保持一致

解决方法: 打开保持一致即可

?

3.使用注入dataSource时报

Failure obtaining db row lock: 第 1 行: FOR UPDATE 子句仅允许用于 DECLARE CU...

改为数据源写在quartz.properties中解决

还不清楚为什么注入不行(解决)

?

org.quartz.jobStore.selectWithLockSQLSELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE描述:这必须是一个从 LOCKS 表查询一行并对这行记录加锁的 SQL 语句。假如未设置,默认值就是 SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE,这能在大部分数据库上工作。{0} 会在运行期间被前面你配置的 TABLE_PREFIX 所替换。

?

?这条sql在sqlserver2000中不能运行修改为:

?

这种方式配置quartz.properties文件需要放在classpath下,而我们项目中都是放在Web-info下

可直接修改为:

?

?

5.在spring配置文件中

?

?以这种方式将scheduler即StdScheduler? scheduler注入到相关service中报找不到该property的错误

?

?

?

热点排行