2015-10-15 61 views
1

我正在使用Maven在Tomcat 8上開發一個Web應用程序,我正在使用c3p0來處理主線程和另外兩個併發線程上的連接,我的連接管理器類在問一個DataSource單例類我爲同步連接實現的,像這樣Tomcat8 + c3p0,連接正在被中斷並自動關閉

public synchronized Connection getConnection() { 
    try { 
     return cpds.getConnection(); 
    } catch (SQLException ex) { 
     logger.error("Error while issuing a pooled connection", ex); 
    } 
    return null; 
} 

,但是當我試圖用他們開始這些連接要麼中斷

09:47:17.164 [QuartzScheduler_Worker-4] ERROR com.myapp.providers.DataSource - Error while issuing a pooled connection 
java.sql.SQLException: An SQLException was provoked by the following failure: java.lang.InterruptedException 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2] 

或接近中等交易和打破任何陳述和結果集E是當時使用的

我配置像這樣

cpds = new ComboPooledDataSource(); 
     cpds.setDriverClass(oracle.jdbc.driver.OracleDriver); 
     cpds.setJdbcUrl(jdbc:oracle:thin:@xx.xxx.xxx.xxx:1521:XE); 
     cpds.setUser("username"); 
     cpds.setPassword("password"); 

     // database connection properties 
     cpds.setInitialPoolSize(10); 
     cpds.setAcquireIncrement(3); 
     cpds.setMaxPoolSize(100); 
     cpds.setMinPoolSize(15); 
     cpds.setMaxStatements(75); 

     // connection pool preferences 
     cpds.setIdleConnectionTestPeriod(60); 
     cpds.setMaxIdleTime(30000); 
     cpds.setAutoCommitOnClose(false); 
     cpds.setPreferredTestQuery("SELECT 1 FROM DUAL"); 
     cpds.setTestConnectionOnCheckin(false); 
     cpds.setTestConnectionOnCheckout(false); 
     cpds.setAcquireRetryAttempts(30); 
     cpds.setAcquireRetryDelay(1000); 
     cpds.setBreakAfterAcquireFailure(false); 

DataSource對象我也寫的是在一個循環中運行,並查詢數據庫n次,但該作品一個小的測試方法精細。

+1

您的crp0配置在哪裏? –

+0

我以編程的方式對其進行配置,我將在短時間內對其進行編輯 – svarog

+1

以及@Steve Waldman的回答,他指向一個已被絞死的線程,所以您是否使用不同的線程來打開連接並使用連接 ?如果你在一個線程中使用連接,這個線程不是上下文感知的(意味着tomcat不知道它的存在),當另一個線程要求連接池時,tomcat積極地中斷第一個線程來傳遞連接第二個線程 – AntJavaDev

回答

2

c3p0-0.9.1.2非常非常古老;請考慮升級到當前量產版本0.9.5.1。

問題既清楚又不那麼清楚。清晰的部分是,正在等待獲取Connections的客戶端線程上正在調用interrupt()。不太清楚的部分是誰在做這件事,爲什麼。

一個猜測是Tomcat本身正在這樣做,因爲客戶端線程掛起時間過長。如果線程掛在getConnection(),這可能是由於連接泄漏和池耗盡。我們在上面看到您如何獲得Connections。你是否保持警惕,確保它們在最後的塊中可靠地被編輯?

您可能會嘗試的一件事是設置一個checkoutTimeout,例如,

cpds.setCheckoutTimeout(5000); // 5 secs 

這實際上不會解決問題,如果連接檢出正在掛起。但不是由神祕的中斷引發的問題,你會看到c3p0 TimeoutExceptions。儘管如此,這將驗證問題在結帳時很長時間,這很可能是由於連接泄漏(缺少對close()的調用)或簡單地從您的負載的maxPoolSize值太低而引起的連接池耗盡。

如果似乎存在連接泄漏,請參閱unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces以獲取幫助追蹤。另請參閱"Configuring to Debug and Workaround Broken Client Applications"

+0

我注意到了舊版本並升級了。問題依然存在。接受你的建議,我已經設置了setCheckoutTimeout(500)並得到:java.sql.SQLException:客戶端嘗試檢出連接超時。 異常。池很快耗盡,我猜想可能是問題所在。 – svarog

+0

(我會嘗試5000而不是500毫秒,通常連接應該在500毫秒內檢出,但如果池暫時耗盡,因爲它需要擴展或因爲其他客戶端正在使用連接但很快會返回它們,可能你可能會偶爾看到那種延遲,我懷疑它不會有太大的區別,但你仍然會看到超時。) –

+0

('unreturnedConnectionTimeout'和'debugUnreturnedConnectionStackTraces'對於查找非常有用連接泄漏。) –