在使用 Spring OpenSymphony Quartz 做計劃任務時,遇到錯誤:
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:
爲了定時執行一項任務,設置了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"。