關於c3p0 ResourcePoolException: Attempted to use a closed or broken resource pool

轉自:https://blog.csdn.net/u011404265/article/details/52848603spring

springmvc-servlet.xml加入sql

<property name="acquireRetryAttempts"> <value>30</value> 數據庫

</property> 後端

<property name="acquireRetryDelay"> <value>100</value>服務器

</property> 網絡

<property name="breakAfterAcquireFailure"> <value>false</value> mvc

</property>異步

出現該問題的緣由是c3p0的自動重連機制:

一、C3P0容錯和自動重連與如下配置參數有關:

  1. breakAfterAcquireFailure :true表示pool向數據庫請求鏈接失敗後標記整個pool爲block並close,就算後端數據庫恢復正常也不進行重連,客戶端對pool的請求都拒絕掉。false表示不會標記 pool爲block,新的請求都會嘗試去數據庫請求connection。默認爲false。所以,若是想讓數據庫和網絡故障恢復以後,pool能繼續請求正常資源必須把此項配置設爲false。
  2. idleConnectionTestPeriod :C3P0會有一個Task檢測pool內的鏈接是否正常,此參數就是Task運行的頻率。默認值爲0,表示不進行檢測。
  3. testConnectionOnCheckout :true表示在每次從pool內checkout鏈接的時候測試其有效性,這是個同步操做,所以應用端的每次數據庫調用,都會先經過測試sql測試其有效性,若是鏈接無效,會關閉此鏈接並剔除出pool,並嘗試從pool內取其餘鏈接,默認爲false,此特性要慎用,會形成至少多一倍的數據庫調用。
  4. testConnectionOnCheckin :true表示每次把鏈接checkin到pool裏的時候測試其有效性,由於是個過後操做,因此是異步的,應用端不須要等待測試結果,但一樣會形成至少多一倍的數據庫調用。
  5. acquireRetryAttempts 和acquireRetryDelay :pool請求取鏈接失敗後重試的次數和重試的頻率。請求鏈接會發生在pool內鏈接少於min值或則等待請求數>池內能提供的鏈接數。
  6. automaticTestTable 、connectionTesterClassName 、preferredTestQuery :表示測試方式,默認是採用 DatabaseMetaData.getTables()來測試connection的有效性,但能夠經過以上配置來定製化測試語句,經過其名字就很好理解其含義,無需過多解釋。
  7. maxIdleTime 和 maxConnectionAge :表示connection的時效性,maxIdleTime和maxConnectionAge不一樣之處在於, maxIdleTime表示idle狀態的connection能存活的最大時間,而 maxConnectionAge表示 connection能存活的絕對時間

二、應用端getConnection拋出exception時, C3P0會測試其connection的有效性,並根據狀態處理此connection,但應用端不會重調。

三、不管是網絡問題仍是遠端數據庫服務器,就算恢復正常後,客戶端pool內其已存在的connection都會失效,要保證應用端調用無誤,必須在checkout到應用端以前刷新這些無效connection

四、breakAfterAcquireFailure=false是關鍵。若是 breakAfterAcquireFailure=true ,一旦pool向數據庫請求鏈接失敗,就會標記pool block並關閉pool,這樣不管數據庫是否恢復正常,應用端都沒法從pool拿到鏈接

五、要想保證網絡和數據庫瞬間的失效100%不會形成應用端getConnection失敗必須開啓 testConnectionOnCheckout。但此特性的代價巨大,建議在應用端作容錯。

六、推薦使用 idleConnectionTestPeriod。能夠根據應用調用頻率權衡一個檢查pool的頻率,這樣能夠在保證性能損耗不大狀況下,儘量的保證pool內connection的有效性

七、若嫌DatabaseMetaData.getTables()性能很差,能夠嘗試經過配置automaticTestTable、connectionTesterClassName、preferredTestQuery來找到一個性能最好的測試語句,只要能驗證connection有效就行

綜上所述,要想保證性能的前提下,本人推薦的配置組合以下:

breakAfterAcquireFailure: false testConnectionOnCheckout: false testConnectionOnCheckin: false idleConnectionTestPeriod: 60 acquireRetryAttempts: 10 acquireRetryDelay: 1000
相關文章
相關標籤/搜索