2015-04-24 72 views
2

使用c3p0時出現問題。在大多數情況下,工作正常,但是在防火牆之後,ocasionally無法檢出連接。問題是需要15分鐘才能識別連接不可用。由於其他連接在15分鐘的間隔期間被檢出並愉快地使用,因此游泳池不會被取消。c3p0連接結帳需要15分鐘時間失敗

日誌:

23 Apr 2015 09:08:16.426 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Testing PooledConnection [[email protected]] on CHECKOUT. 

,15分鐘後:

23 Apr 2015 09:23:43.073 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Test of PooledConnection [[email protected]] on CHECKOUT has FAILED. 
java.sql.SQLException: Connection is invalid 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:572) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.finerLoggingTestPooledConnection(C3P0PooledConnectionPool.java:451) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.finerLoggingTestPooledConnection(C3P0PooledConnectionPool.java:443) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishResourceOnCheckout(C3P0PooledConnectionPool.java:336) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.resourcepool.BasicResourcePool.attemptRefurbishResourceOnCheckout(BasicResourcePool.java:1727) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:553) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:756) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:683) [c3p0-0.9.5.jar:0.9.5] 
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140) [c3p0-0.9.5.jar:0.9.5] 

再些木柴:

23 Apr 2015 09:23:43.073 [EventProcessor-1] DEBUG c.m.v.r.BasicResourcePool - A resource could not be refurbished for checkout. [[email protected]] 
java.sql.SQLException: Connection is invalid 
... 
23 Apr 2015 09:23:43.074 [EventProcessor-1] DEBUG c.m.v.r.BasicResourcePool - Resource [[email protected]] could not be refurbished in preparation for checkout. Will try to find a better resource. 
23 Apr 2015 09:23:43.074 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.r.BasicResourcePool - Preparing to destroy resource: [email protected] 
23 Apr 2015 09:23:43.074 [EventProcessor-1] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Testing PooledConnection [[email protected]] on CHECKOUT. 
23 Apr 2015 09:23:43.074 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.c.i.C3P0PooledConnectionPool - Preparing to destroy PooledConnection: [email protected] 
23 Apr 2015 09:23:43.076 [C3P0PooledConnectionPoolManager[identityToken->67oy4j981qzvkd716hgow4|4177fc5c]-HelperThread-#2] DEBUG c.m.v.c3p0.impl.NewPooledConnection - Failed to close physical Connection: [email protected] 
java.sql.SQLRecoverableException: IO Error: Broken pipe 
    at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:612) ~[ojdbc6_g-11.2.0.1.0.jar:11.2.0.1.0] 
    at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:5094) ~[ojdbc6_g-11.2.0.1.0.jar:11.2.0.1.0] 
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:642) [c3p0-0.9.5.jar:0.9.5] 

C3P0配置:

 ComboPooledDataSource ods = new ComboPooledDataSource(); 
... 
     ods.setInitialPoolSize(5); 
     ods.setMinPoolSize(5); 
     ods.setMaxPoolSize(10); 
     ods.setMaxStatements(50); 

     ods.setTestConnectionOnCheckout(true); 

所以沒什麼特別的。我知道連接丟失是可能的,因此在結賬時測試連接。任何想法爲什麼它需要很長時間才能驗證/失敗連接?我們正在使用Oracle數據庫。 謝謝。

回答

1

它看起來像是連接被防火牆終止時的情況,即根本沒有響應發回,即使是沒有數據的TCP ACK也是如此。在這種情況下,驗證連接的查詢將永遠不會返回。這是在套接字/ jdbc驅動程序級別。

解決方案:

  • 找出防火牆斷開連接策略(在本例中1小時)
  • 設置c3p0.maxConnectionAge財產強制C3P0重新連接每隔X秒。
2

首先,我假定您已驗證您的日誌消息之間沒有該Connection的簽出。很明顯,你會期望很多消息像......

Testing PooledConnection [[email protected]] on CHECKOUT. 

......在最終消息之前的失敗之前。很多這些信息會更早發生。理想情況下,只有在失敗之前的最終信息比你所看到的15分鐘更接近檢測失敗。

假設這是最終的消息,那麼這個問題與你的連接如何死亡有關。 c3p0運行測試,然後等待成功完成或異常。如果您的Connection以某種方式死亡,那麼Connection測試只會掛起15分鐘,那麼您可能會看到您所看到的內容。

以下是一些建議。

  1. 使用c3p0的idleConnectionTestPeriod在客戶端簽出之前理想地檢測這些故障,以便客戶端不太可能遇到長時間掛起。 (您也可以在辦理登機手續時進行測試。)
  2. 找出正在運行的連接測試的類型。您正在使用c3p0 0.9.5,因此如果您的驅動程序支持它,則默認測試是對Connection.isValid()的調用,該調用應該很快。我沒有看到任何日誌引用了實際測試失敗的堆棧跟蹤(也許它是一個截斷的根本原因異常?它肯定會被一個名爲com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool的日誌記錄器記錄在FINER/DEBUG級別)Verify(來自堆棧跟蹤)您的驅動程序正在使用快速連接測試而不是c3p0的默認連接測試。如果不是(可能是因爲你的驅動程序不支持),那麼考慮快速設置preferredTestQuery
  3. 你可以試試maxAdministrativeTaskTime,但只有在連接測試掛起響應中斷()調用的情況下才可能真正起作用。

無論如何,我希望這不是完全沒用!

+0

嗨史蒂夫,謝謝你的回答。其中一些選項會有所幫助,但我認爲我現在明白了實際的問題 - 防火牆以一種停止響應的方式丟棄連接。我將提供一個單獨的解決方案的答案。 – Vladimir