一套S2SH的應用,現用單線程,連續發1000個請求,用的DBCP鏈接池,結果報數據庫鏈接不夠用:
ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
在JAVA加上LOG:
log.info("active: " + dataSource.getNumActive() + " (max: "
+ dataSource.getMaxActive() + ") " + "idle: " + dataSource.getNumIdle()
+ "(max: " + dataSource.getMaxIdle() + ")");
結果顯示為:
active: 25 (max: 100) idle: 0(max: 30)
active的數量一直增加,但idle的數量一直為0。當程序向鏈接池要鏈接的時候,如果池沒有,就會新建一個,active數就會加1,關閉鏈接后,鏈接會返回池,idle數加1。idle為0則表示池里沒有鏈接。
這樣說明鏈接一直在創建,沒有關閉放回池里。但鏈接是由SPRING和HIBERNATE管理的,代碼中沒有關閉鏈接的語句。之后試了N多配置,都還沒解決,如增加maxActive數等。最后,加上這一行,問題才終于解決:
<prop key="hibernate.connection.release_mode">after_transaction</prop>
這里默認值是auto,如果是用JTA事務才適用,如果是JDBC事務,就只能用after_transaction。
這樣每次事務結束后,就會關閉鏈接返回鏈接池。