4

我有一个正在工作的 spring 应用程序,并且正在尝试向它添加 Quartz 作业调度。我已经从另一个正在工作的项目中复制/粘贴/修改了 spring 配置,但是这个项目在启动时一直抛出异常。我正在使用石英 2.2 和弹簧 3.2.1。我已经包含了我的 spring 配置和异常堆栈跟踪。任何诊断此问题的帮助将不胜感激。

<!-- task scheduling -->    
<bean id="emailOrganizerLink" class="it.cause.cron.EmailOrganizerLink" />

<bean id="emailOrganizerLinkJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="it.cause.cron.EmailOrganizerLinkJob" />
    <property name="durability" value="true" />
</bean>

<bean id="emailOrganizerLinkTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="emailOrganizerLinkJob" />
    <!-- run every morning at 5am (every minute for testing) -->
    <property name="cronExpression" value="0 */1 * * * ?" />
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
    lazy-init="false" autowire="no">
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="overwriteExistingJobs" value="true" />
    <property name="waitForJobsToCompleteOnShutdown" value="true" />
    <property name="autoStartup" value="true" />

    <property name="triggers">
        <list>
            <ref bean="emailOrganizerLinkTrigger" />
        </list>
    </property>

    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceName">CauseITBatchScheduler</prop>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">300000</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">5</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
        </props>
    </property>

    <property name="schedulerContextAsMap">
        <map>
           <entry key="emailOrganizerLink" value-ref="emailOrganizerLink" />
        </map>
    </property>     
</bean> 

<context:property-placeholder location="classpath:hibernate.properties" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>${hibernate.connection.driver_class}</value>
    </property>
    <property name="url">
        <value>${hibernate.connection.url}</value>
    </property>
    <property name="username">
        <value>${hibernate.connection.username}</value>
    </property>
    <property name="password">
        <value>${hibernate.connection.password}</value>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="CauseIT" />
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="${hibernate.dialect}" />
            <property name="showSql" value="${hibernate.showSql}" />
            <property name="generateDdl" value="${hibernate.generateDdl}" />
        </bean>
    </property>
    <!--
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
        </props>
    </property>
    -->
</bean>

Sep 24, 2013 10:47:41 AM org.quartz.impl.StdSchedulerFactory instantiate
INFO: Using default implementation for ThreadExecutor
Sep 24, 2013 10:47:41 AM org.quartz.core.SchedulerSignalerImpl 
INFO: Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
Sep 24, 2013 10:47:41 AM org.quartz.core.QuartzScheduler 
INFO: Quartz Scheduler v.2.2.0 created.
Sep 24, 2013 10:47:42 AM org.quartz.impl.jdbcjobstore.JobStoreSupport initialize
INFO: Using db table-based data access locking (synchronization).
Sep 24, 2013 10:47:42 AM org.quartz.impl.jdbcjobstore.JobStoreCMT initialize
INFO: JobStoreCMT initialized.
Sep 24, 2013 10:47:42 AM org.quartz.core.QuartzScheduler initialize
INFO: Scheduler meta-data: Quartz Scheduler (v2.2.0) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'CauseIts-MacBook-Air.local1380034061295'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 5 threads.
  Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered.

Sep 24, 2013 10:47:42 AM org.quartz.impl.StdSchedulerFactory instantiate
INFO: Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
Sep 24, 2013 10:47:42 AM org.quartz.impl.StdSchedulerFactory instantiate
INFO: Quartz scheduler version: 2.2.0
Sep 24, 2013 10:47:42 AM org.quartz.core.QuartzScheduler setJobFactory
INFO: JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@3f5756de
2013-09-24 10:47:46,004 [ERROR]: Job registration exception overridden by rollback exception
org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: No operations allowed after connection closed. [See nested exception: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.]
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:157)
    at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:113)
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:238)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInLock(JobStoreSupport.java:3701)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1085)
    at org.quartz.core.QuartzScheduler.addJob(QuartzScheduler.java:999)
    at org.quartz.core.QuartzScheduler.addJob(QuartzScheduler.java:988)
    at org.quartz.impl.StdScheduler.addJob(StdScheduler.java:268)
    at org.springframework.scheduling.quartz.SchedulerAccessor.addJobToScheduler(SchedulerAccessor.java:342)
    at org.springframework.scheduling.quartz.SchedulerAccessor.addTriggerToScheduler(SchedulerAccessor.java:365)
    at org.springframework.scheduling.quartz.SchedulerAccessor.registerJobsAndTriggers(SchedulerAccessor.java:303)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:511)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:608)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:680)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
    at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1304)
    at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1296)
    at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4511)
    at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4476)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.quartz.impl.jdbcjobstore.AttributeRestoringConnectionInvocationHandler.invoke(AttributeRestoringConnectionInvocationHandler.java:73)
    at com.sun.proxy.$Proxy68.prepareStatement(Unknown Source)
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:88)
    ... 35 more
4

1 回答 1

4

为了使 2.2 调度程序工作,您需要在 QRTZ_LOCK 表中为您的特定调度程序名称输入记录。

INSERT INTO QRTZ_LOCKS values('CauseITBatchScheduler', 'TRIGGER_ACCESS'); 
INSERT INTO QRTZ_LOCKS values('CauseITBatchScheduler','JOB_ACCESS'); 
INSERT INTO QRTZ_LOCKS values('CauseITBatchScheduler','CALENDAR_ACCESS'); 
INSERT INTO QRTZ_LOCKS values('CauseITBatchScheduler','STATE_ACCESS'); 
INSERT INTO QRTZ_LOCKS values('CauseITBatchScheduler','MISFIRE_ACCESS');
于 2013-09-24T18:37:13.640 回答