DBCP代碼研讀以及就資料庫連接失效的解決

來源:互聯網
上載者:User

問題

網上很多評論說DBCP有很多BUG,但是都沒有指明是什麼BUG,只有一部分人說資料庫如果因為某種原因斷掉後再DBCP取道的串連都是失效的串連,而沒有重新取。就此研讀了一下DBCP的代碼,共用之。

分析

DBCP使用apache的對象池ObjectPool作為串連池的實現,有以下主要的方法

Object borrowObject() throws Exception;從對象池取得一個有效對象

void returnObject(Object obj) throws Exception;使用完的對象放回對象池

void invalidateObject(Object obj) throws Exception;使對象失效

void addObject() throws Exception;產生一個新對象

ObjectPool的一個實現就是GenericObjectPool,這個類使用對象工廠PoolableObjectFactory實現對象的產生,失效檢查等等功能,以其實現資料庫連接工廠PoolableConnectionFactory做以說明,主要方法:

     Object makeObject() throws Exception; 使用ConnectionFactory產生新串連

     void destroyObject(Object obj) throws Exception;關閉串連

     boolean validateObject(Object obj); 驗證串連是否有效,如果_validationQuery不空,則使用該屬性作為驗證串連是否有效sql語句,查詢資料庫

     void activateObject(Object obj) throws Exception;啟用連線物件

     void passivateObject(Object obj) throws Exception; 關閉串連產生過的Statement和ResultSet,使串連處於非使用中

而GenericObjectPool有幾個主要屬性

     _timeBetweenEvictionRunsMillis:失效檢查線程已耗用時間間隔,預設-1

     _maxIdle:對象池中對象最大個數

     _minIdle:對象池中對象最小個數

     _maxActive:可以從對象池中取出的對象最大個數,為0則表示沒有限制,預設為8

在構造GenericObjectPool時,會產生一個內嵌類Evictor,實現自Runnable介面。如果 _timeBetweenEvictionRunsMillis大於0,每過_timeBetweenEvictionRunsMillis毫秒 Evictor會調用evict()方法,檢查對象的閑置時間是否大於 _minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小於等於0時則忽略,預設為30 分鐘),是則銷毀此對象,否則就啟用並校正對象,然後調用ensureMinIdle方法檢查確保池中對象個數不小於_minIdle。在調用
returnObject方法把對象放回對象池,首先檢查該對象是否有效,然後調用PoolableObjectFactory 的passivateObject方法使對象處於非使用中。再檢查對象池中對象個數是否小於_maxIdle,是則可以把此對象放回對象池,否則銷毀此對象

還有幾個很重要的屬性,_testOnBorrow、_testOnReturn、_testWhileIdle,這些屬性的意義是取得、返回對象和空閑時是否進行驗證,檢查對象是否有效,預設都為false即不驗證。所以當使用DBCP時,資料庫連接因為某種原因斷掉後,再從串連池中取得串連又不進行驗證,這時取得的串連實際已經時無效的資料庫連接了。網上很多說 DBCP的bug應該都是如此吧,只有把這些屬性設為true,再提供_validationQuery語句就可以保證資料庫連接始終有效了,oracle資料庫可以使用SELECT
COUNT(*) FROM DUAL,不過DBCP要求_validationQuery語句查詢的記錄集必須不為空白,可能這也可以算一個小小的BUG,其實只要_validationQuery語句執行通過就可以了。

注意事項

所以使用DBCP串連池放必須注意構造GenericObjectPool對象時

     validationQuery:SELECT COUNT(*) FROM DUAL

       _testOnBorrow、_testOnReturn、_testWhileIdle:最好都設為true

       _minEvictableIdleTimeMillis:大於0 ,進行串連空閑時間判斷,或為0,對閒置串連不進行驗證

     _timeBetweenEvictionRunsMillis:失效檢查線程已耗用時間間隔,如果小於等於0,不會啟動檢查線程

 

轉載連結地址:http://blog.csdn.net/sandyen/article/details/723635

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.