2010-03-23 96 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