Spring Quartz *.QRTZ_LOCKS' doesn't exist

 

 

ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: Table 'zp60v1_db.QRTZ_LOCKS' doesn't exist [See nested exception: com.MySQL.jdbc.exceptions.MySQLSyntaxErrorException: Table 'zp60v1_db.QRTZ_LOCKS' doesn't exist]]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean

....

 

开发环境:
JDK 1.6
GWT 2.0
SmartGwt pro 2.0
hibernate 3.2
Spring 2.5

 

applicationContext.xml:

 

[xhtml] view plain copy
 
  1. <beans default-autowire=”autodetect”> <!–autowire is the cause of exception–>  
  2.                <bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource”>  
  3.                       ……  
  4.                </bean>  
  5.                <bean id=”sessionFactory” class=”org.springframework.orm.hibernate3.LocalSessionFactoryBean”>  
  6.                      ……  
  7.                </bean>  
  8.                     …….  
  9.               <bean id=”cronReportTrigger” class=”org.springframework.scheduling.quartz.CronTriggerBean”>  
  10.                     ……  
  11.               </bean>  
  12.               <bean id=”schedulerFactoryBean” class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>  
  13.                         <property name=”triggers”>  
  14.                               <list>  
  15.                                       <ref bean=”cronReportTrigger”/>  
  16.                               </list>  
  17.                         </property>  
  18.               </bean>  
  19.         </beans>  

 

 

为了定时执行一项任务,设置了Quartz , 但是运行后异常" Failure obtaining db row lock: Table ‘hibernate.qrtz_locks’ doesn’t exist“,相信你肯定会感到困惑,甚至也许会奇怪为什么 SchedulerFactoryBean 和数据持久层有关。

 

原因:

事实上,这个异常是由于 Spring 的 autowire 属性引起的,SchedulerFactoryBean  类含有方法 : setDataSource. 因为autowire 属性使用了 autodetect , 并且也设置了 datasource 在项目中, spring 容器就自动将 dataSource 注入到SchedulerFactoryBean, 而SchedulerFactoryBean将从 dataSource 中查找计划任务。 但 dataSource 中并没有任务,因此抛出了异常。

幸运的是,当你知道了根本原因,就知道如何避免了。

 

解决方法:

不论 spring 的 default-autowire 设置为"autodetect " 还是 "byName" ,都会出现 *.QRTZ_LOCKS' doesn't exist

方法一: 不使用 default-autowire 属性;

方法二: 在不改变 spring default-autowire  属性的前提下, 给 SchedulerFactoryBean  设置 autowire="no"。

 

 

[xhtml] view plain copy
 
  1. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">  
  2.         <property name="triggers">  
  3.             <list>  
  4.                 <ref bean="simpleTriggerBean" />  
  5.             </list>  
  6.         </property>  
  7. </bean>  

 

 
 
  • 原理:
<bean id="scheduler" lazy-init="false"
      class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
此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
推荐此法
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
          default-autowire="byName"
           > 
<bean id="scheduler" lazy-init="false" autowire="no"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
 
posted @ 2017-02-20 20:09  牧之丨  阅读(3119)  评论(0编辑  收藏  举报