在最新版本的DBCP和C3P0上,使用Spring的Ibatis支持,我遇到了兩個泄漏連接的問題。帶C3P0或DBCP的Spring ORM正在泄漏連接
該方案是有一個運行SQL的日誌鎖定多個表。這會導致我的池中的連接在用戶觸發鎖定表的查詢時最大化。最後,管理員進入MySQL並在長時間運行的SQL上執行kill query <id>
。
如果有足夠的線程(在我的周圍50個或更多的情況下),它正在等待繞了DB線程在游泳池進行檢查回來,然後我看到類似線程轉儲如下:
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
- locked <0x00002aaacbb01118> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
at
或
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
- locked <0x00002aab0f030620> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
at
和這些線程等待撒手人寰。
如果該池已最大化,並且只有少數(約5個)線程正在等待池中的空閒連接,則不會發生這種情況。
我知道有配置可以解決這個問題(設置超時等),但我有興趣爲什麼這是發生在第一個地方?爲什麼當有50個或更多的線程在等待連接,並且我終止了長時間運行的SQL時,活動線程不會返回到池中?
更新:我應該明確表示,我使用Spring 3.0.2和 ibatis的2.3。我使用SqlMapClientTemplate,它爲我管理我的 連接。此時,我開始認爲它是 Ibatis 2.3沒有正確處理重負載。
您是否在執行查詢後關閉連接? – BalusC
@BalusC我對Spring使用ComboPooledDataSource或BasicDataSource,所以我不管理在我的Java代碼中關閉這些連接的open c。也許春天是問題。 – stevebot
你應該顯示一些你如何使用連接的代碼。僅僅因爲你使用Spring來管理數據源,並不意味着它會爲你關閉連接。 – Nick