1. 程式人生 > >jdbc C3P0容錯和自動重連

jdbc C3P0容錯和自動重連

1)C3P0容錯和自動重連與以下配置引數有關:

breakAfterAcquireFailure :true表示pool向資料庫請求連線失敗後標記整個pool為block並close,就算後端資料庫恢復正常也不進行重連,客戶端對pool的請求都拒絕掉。false表示不會標記 pool為block,新的請求都會嘗試去資料庫請求connection。預設為false。因此,如果想讓資料庫和網路故障恢復之後,pool能繼續請求正常資源必須把此項配置設為false
idleConnectionTestPeriod :C3P0會有一個Task檢測pool內的連線是否正常,此引數就是Task執行的頻率。預設值為0,表示不進行檢測。
testConnectionOnCheckout :true表示在每次從pool內checkout連線的時候測試其有效性,這是個同步操作,因此應用端的每次資料庫呼叫,都會先通過測試sql測試其有效性,如果連線無效,會關閉此連線並剔除出pool,並嘗試從pool內取其他連線,預設為false,此特性要慎用,會造成至少多一倍的資料庫呼叫。
testConnectionOnCheckin :true表示每次把連線checkin到pool裡的時候測試其有效性,因為是個事後操作,所以是非同步的,應用端不需要等待測試結果,但同樣會造成至少多一倍的資料庫呼叫。
acquireRetryAttempts 和acquireRetryDelay :pool請求取連線失敗後重試的次數和重試的頻率。請求連線會發生在pool內連線少於min值或則等待請求數>池內能提供的連線數

automaticTestTable 、connectionTesterClassName 、preferredTestQuery :表示測試方式,預設是採用 DatabaseMetaData.getTables()來測試connection的有效性,但可以通過以上配置來定製化測試語句,通過其名字就很好理解其含義,無需過多解釋
maxIdleTime 和 maxConnectionAge :表示connection的時效性,maxIdleTime和maxConnectionAge不同之處在於, maxIdleTime表示idle狀態的connection能存活的最大時間,而 maxConnectionAge表示 connection能存活的絕對時間

2)應用端getConnection丟擲exception時, C3P0會測試其connection的有效性,並根據狀態處理此connection,但應用端不會重調。

3)無論是網路問題還是遠端資料庫伺服器,就算恢復正常後,客戶端pool內其已存在的connection都會失效,要保證應用端呼叫無誤,必須在checkout到應用端之前重新整理這些無效connection

4)breakAfterAcquireFailure=false是關鍵。如果 breakAfterAcquireFailure=true ,一旦pool向資料庫請求連線失敗,就會標記pool block並關閉pool,這樣無論資料庫是否恢復正常,應用端都無法從pool拿到連線

5)要想保證網路和資料庫瞬間的失效100%不會造成應用端getConnection失敗必須開啟 testConnectionOnCheckout。但此特性的代價巨大,建議在應用端做容錯。

6)推薦使用 idleConnectionTestPeriod。可以根據應用呼叫頻率權衡一個檢查pool的頻率,這樣可以在保證效能損耗不大情況下,儘可能的保證pool內connection的有效性

7)若嫌DatabaseMetaData.getTables()效能不好,可以嘗試通過配置automaticTestTable、connectionTesterClassName、preferredTestQuery來找到一個性能最好的測試語句,只要能驗證connection有效就行

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

breakAfterAcquireFailure: false
testConnectionOnCheckout: false
testConnectionOnCheckin: false
idleConnectionTestPeriod: 60
acquireRetryAttempts: 10
acquireRetryDelay: 1000

但需要注意的是以上的配置不能保證100%應用端getConnection無誤,如果應用端不能發生getConnection錯誤,需要自行考慮容錯和重試機制。

在以上配置下,當網路或資料庫發生瞬間變動的情況下,會有如下事情發生:

1)自動測試idleConnection的 task輪訓檢測pool,對每個connction通過DatabaseMetaData.getTables()來測試有效性,並剔除無效連線。

2)根據請求情況和配置,pool向資料庫請求新連線並加入池內

3)應用端getConnection->是否發生異常->如果發生異常,檢驗其有效性,並剔除出pool->如果沒有發生異常(自動檢查task之前已檢測),呼叫成功

轉載自 風歸雲隱

以上是基於客戶端的重連機制,其實重連可以讓服務端來做,效果更好~