石英在负载下抛出死锁

时间:2010-03-23 03:28:09

标签: hibernate spring quartz-scheduler

我们正在使用Quartz with Spring,当石英配置了超过1个线程时,我们的配置会抛出死锁。我开始相信这是因为我们没有使用Spring正确配置我们的石英,但是我找不到足够的文档来说明如何配置两者才能很好地运行。

我们在Windows和Linux环境中运行 - 指向MSSQL和Oracle DB。使用这两个操作系统,我们可以抛出以下死锁错误......

我们一直在抛出这些死锁错误。我们在重载下运行,在几分钟内插入数百个石英触发器。

2010-03-17 18:52:31,737 [] [] ERROR [DFScheduler_Worker-42] core.ErrorLogger core.ErrorLogger (QuartzScheduler.java:2185) - An error occured while marking executed job complete. job= 'BPM.6e41a6567f0000020100362a51dc7a50'

org.quartz.JobPersistenceException: Couldn't remove trigger: Transaction (Process ID 87) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. [See nested exception: com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 87) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.removeTrigger(JobStoreSupport.java:1469)at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggeredJobComplete(JobStoreSupport.java:2978)at org.quartz.impl.jdbcjobstore.JobStoreSupport$39.execute(JobStoreSupport.java:2962) at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:3713)at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3747)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3709)at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggeredJobComplete(JobStoreSupport.java:2958)at org.quartz.core.QuartzScheduler.notifyJobStoreJobComplete(QuartzScheduler.java:1727)at org.quartz.core.JobRunShell.run(JobRunShell.java:273)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:534)

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 87) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source) at 
...
org.quartz.impl.jdbcjobstore.StdJDBCDelegate.deleteSimpleTrigger(StdJDBCDelegate.java:1820) at org.quartz.impl.jdbcjobstore.JobStoreSupport.deleteTriggerAndChildren(JobStoreSupport.java:1345 at org.quartz.impl.jdbcjobstore.JobStoreSupport.removeTrigger(JobStoreSupport.java:1453 ... 9 more

这是我的quartz.properties文件的样子:

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 50
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.selectWithLockSQL = SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?

1 个答案:

答案 0 :(得分:0)

您使用SchedulerFactoryBean吗?文档是:http://static.springsource.org/spring/docs/2.5.x/reference/scheduling.html它将完全消除对实际quartz.properties的需求,您可以使用您在应用程序其余部分中使用的数据源。这有明显的优势(比如连接池中的可重用连接),至少对我来说,调试时间稍微容易一些。

以下是我在旧项目中看起来如何的片段:

<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="quartzProperties"> <!--  quartz attributes, configurable -->
        <value>
            org.quartz.scheduler.rmi.export = false
            org.quartz.scheduler.rmi.proxy = false
            org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
            org.quartz.threadPool.threadCount = ${threadCount}
            org.quartz.threadPool.threadPriority = 5
            org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
            org.quartz.jobStore.useProperties = false
            org.quartz.jobStore.driverDelegateClass = ${driverDelegate}
            org.quartz.jobStore.tablePrefix = QRTZ_
            org.quartz.jobStore.isClustered = false
        </value>
    </property>
    <property name="autoStartup" value="false" /> 
    <property name="waitForJobsToCompleteOnShutdown" value="false" />
    <property name="dataSource" ref="dataSource" />
</bean>

和通常的数据源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    ....
    <property name="validationQuery" value="SELECT 1" />
    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="true" />
    <property name="testOnReturn" value="true" />
</bean>

显然,quartzProperties与文件中的属性类似,但是一旦我从quarts.properties切换到Spring类,我发现应用程序的一般行为更好。这也有助于我只有一个数据源实际访问数据库。