2010-03-23 95 views
1

我们在Spring中使用Quartz,当石英配置了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 = ? 
+0

没有看到你的配置是什么,我们不能评论它可能是错的 – skaffman 2010-03-23 08:32:01

回答

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类,我发现应用程序的一般行为更好。这也有助于我只有一个数据源实际访问数据库。

+0

我们也一直在使用spring类。不过,我也会尝试你的配置。我注意到你没有配置非事务性数据源。这是为什么?我只是想把所有这些都包括在内。 – Khandelwal 2010-03-23 16:36:02

+0

有趣的问题。由于没有真正完成数据源设置,我不能真正回答它。包含这些片段的特定项目由于其查询的db查询类型而需要事务数据源,但其他项目使用相同的设置(每个项目一个事务数据源)。 – laura 2010-03-24 09:51:55