Quartz 的”Table ‘database.qrtz_locks’ doesn’t exist异常”

spring quartz 常见的”Table ‘database.qrtz_locks’ doesn’t exist异常”

原因:出现此异常,通常是因为spring配了

原理: 此bean会试图访问数据库获取quartz的一些管理表信息,自然访问数据库时需要注入dataSource bean,当缺省autowire为no,则没有dataSource bean被注入,quartz会认为项目没连数据库,会BYPASS这个访问管理表的功能. 当你配置了default-autowire=byName时,dataSource bean被自动注入,这时quartz认为项目既然能连到数据库,就想当然的认为对应的那些表一定存在,没找到时就出异常.

解决办法:
1.去掉default-autowire=byName即可 此法简单,但往往很难决定,因为缺省,谁也不会傻乎乎的显示配这么一条,配了它一定是有用到它的地方.你愿不愿意牺牲这部分byName注入的功能?
2.在库中建对应的表 此法不可取,因为非常麻烦,要建很多表 CREATE TABLE QRTZ_LOCKS CREATE TABLE QRTZ_JOB_DETAILS CREATE TABLE QRTZ_TRIGGERS CREATE TABLE QRTZ_FIRED_TRIGGERS CREATE TABLE QRTZ_JOB_LISTENERS 少一张,spring都报异常, 这是为大型调度功能准备的.你要有上百个任务,可能需要它.
3.bean里直接关掉autowired 推荐此法

quartz无法启动的原因

场景:spring集成quartz,在spring配置文件中配置quartz相关参数。
在以往的工作中,quartz经常无法启动,今天就根据以前经验,总结一下,供大家参考。

原因一:ID冲突

quartz的两个基本单元是Job和Trigger,它们在内存中分别以jobName+groupName和triggerName+GrupName唯一标识,如果两个job的名字和群组都相同,则必然会有一个job无法启动。

原因二:default-lazy-init=”true”

若在spring配置文件中配置了quartz相关参数,则不能够设置default-lazy-init=”true”,否则定时任务不会触发;若工程有多个spring配置文件,则只需当前配置quartz的文件不设置default-lazy-init=”true”即可。

原因三:default-autowire=”byName”

若在spring配置文件中配置了quartz相关参数,则不能够设置default-autowire=”byName”属性,否则后台会报Table ‘database.qrtz_locks’ doesn’t exist异常,这是因为若使用了autowire,spring集成quartz,会默认使用数据库存储job状态(而不是存储在内存中),spring会自动将dataSource(hibernate配置的数据库)配置为quartz存储数据库,而我们的数据库中又没有quartz所需的数据表,因此就会报出如上异常;若工程有多个spring配置文件,则只需当前配置quartz的文件不设置default-autowire=”byName”即可。

原因四: 特别注意一点,与Spring整合必须使用Quartz1.8.x及以下版本

使用cronTriggerBean子类,动态设置cronExpression

Quartz的使用前准备:

1.引入必要的jar包:

  • quartz_all_xxx.jar 或者quartz_xxx.jar
  • slf4j_api_xx.jar quartz所需要的日志工具

quartz知识简单了解: 2.quartz的两种作业存储方式:

  • RAMJobStore,利用内存来持久化调度程序信息
  • JDBC作业存储,利用JDBC驱动和后台库中保存的调度程序信息

3.Quartz两种触发器

  • simpleTrigger 适合执行简单的调度任务
  • cronTrigger 使用cron表达式,调度相对复杂的任务

4.quartz调度器—将任务和触发器关联起来。 由scheduler接口体现,该接口主要定义了三个方法:

  • void addJob(JobDetail jobDetail, Boolean replace)
  • Date scheduleJob(JobDetail jobDetail, Trigger trigger) //使用trigger类控制该job
  • Date scheduleJob(Trigger trigger) //添加触发器调度作业

在spring中使用quartz,创建quartz作业bean的两种方法: 1.使用JobDetailBean包装QuartzBean子类的实例

  • 创建一个Quartz的作业bean,但是这个bean必须要继承QuartzJobBean抽象类,其中要实现一个executeInternal(JobExecutionContext ctx)方法。

2.使用MethodInvokingJobDetailFactoryBean配置方法(如下例Spring-action.xml 配置)

3.Spring-action.xml 配置内容:

 

QuarzDemo类

 

注意:

1.lazy-init如果设置为true,这任务工程在服务器启动时不会加载。所以这里必须设置为false。

2.由于在上边的配置中定义的了default-autowire=”byName”, Spring会自动注入quartz中的datasource bean,所以会报异常。

解决方法:在bean中关掉autowired