1. 程式人生 > >深入理解資料庫連線池DBCP

深入理解資料庫連線池DBCP

1.DBCP簡介

    DBCP(DataBase connection pool),資料庫連線池。是 apache 上的一個 java 連線池專案,也是 tomcat 使用的連線池元件。單獨使用dbcp需要2個包:commons-dbcp.jar,commons-pool.jar由於建立資料庫連線是一個非常耗時耗資源的行為,所以通過連線池預先同資料庫建立一些連線,放在記憶體中,應用程式需要建立資料庫連線時直接到連線池中申請一個就行,用完後再放回去。

    Tomcat 的連線池正是採用該連線池來實現的。該資料庫連線池既可以與應用伺服器整合使用,也可由應用程式獨立使用。Tomcat通過JAR包tomcat-dbcp.jar集成了連線池DBCP的功能,通過在context.xml中配置連線池的方式引入DBCP連線池,也可以在server.xml檔案中配置全域性的連線池。

2.DBCP與DBCP2的區別

2.1 依賴的JAR包不同

(1)DBCP依賴的JAR包是commons-dbcp-1.*.jar和commons-pool-1.*.jar

(2)DBCP2依賴的JAR包是commons-dbcp2-2.*.jar和commons-pool2-2.*.jar

2.2 依賴的JDK版本不同

(1)DBCP2只在JAVA7下編譯和執行(JDBC4.1)

(2)DBCP1.4只在JAVA6下編譯和執行(JDBC4)

(3)DBCP1.3只在JAVA1.4~1.5下編譯和執行(JDBC3)

2.3 更強大的效能和支援更多的功能

DBCP2基於commons-pool2,效能是會有提升,並且支援JMX

2.4 配置引數不同

比如maxActive 改成 maxTotal

3.DBCP2引數配置說明

3.1常用連結配置

引數描述
username傳遞給JDBC驅動的用於建立連線的使用者名稱
password傳遞給JDBC驅動的用於建立連線的密碼
url傳遞給JDBC驅動的用於建立連線的URL
driverClassName使用的JDBC驅動的完整有效的java 類名
connectionProperties當建立新連線時被髮送給JDBC驅動的連線引數,格式必須是 [propertyName=property;]。

3.2 資料來源連線數量配置

引數預設值描述
initialSize0初始化連線:連線池啟動時建立的初始化連線數量,1.2版本後支援
maxTotal8

最大活動連線:連線池在同一時間能夠分配的最大活動連線的數量, 如果設定為非正數則表示不限制.

dbcp1.X為maxActive

maxIdle8最大空閒連線:連線池中容許保持空閒狀態的最大連線數量,超過的空閒連線將被釋放,如果設定為負數表示不限制
minIdle0最小空閒連線:連線池中容許保持空閒狀態的最小連線數量,低於這個數量將建立新的連線,如果設定為0則不建立
maxWaitMillis無限

最大等待時間:當沒有可用連線時,連線池等待連線被歸還的最大時間(以毫秒計數),超過時間則丟擲異常

,如果設定為-1表示無限等待

dbcp1.X為maxWait


3.3 事務屬性配置

引數預設值描述
defaultAutoCommittrue連線池建立的連線的預設的auto-commit狀態
defaultReadOnlydriver default

連線池建立的連線的預設的read-only狀態. 如果沒有設定則setReadOnly方法將不會被呼叫

.(某些驅動不支援只讀模式,比如:Informix)

defaultTransactionIsolationdriver default連線池建立的連線的預設的TransactionIsolation狀態. 下面列表當中的某一個: (參考javadoc) 
NONE、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE
defaultCatalog連線池建立的連線的預設的catalog

3.4 資料來源連線健康狀況檢查

引數預設值描述
validationQuery

SQL查詢,用來驗證從連線池取出的連線,在將連線返回給呼叫者之前.如果指定,

則查詢必須是一個SQL SELECT並且必須返回至少一行記錄

testOnBorrowtrue指明是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個.
注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
testOnReturnfalse指明是否在歸還到池中前進行檢驗.
注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
testWhileIdlefalse指明連線是否被空閒連接回收器(如果有)進行檢驗.如果檢測失敗,則連線將被從池中去除.
注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
timeBetweenEvictionRunsMillis-1

在空閒連接回收器執行緒執行期間休眠的時間值,以毫秒為單位.如果設定為非正數

,則不執行空閒連接回收器執行緒

numTestsPerEvictionRun3在每次空閒連接回收器執行緒(如果有)執行時檢查的連線數量
minEvictableIdleTimeMillis10006030連線在池中保持空閒而不被空閒連接回收器執行緒(如果有)回收的最小時間值,單位毫秒

3.5 快取語句

引數預設值描述
poolPreparedStatementsfalse開啟池的prepared statement 池功能
maxOpenPreparedStatements不限制statement池能夠同時分配的開啟的statements的最大數量, 如果設定為0表示不限制

3.6 連線洩露回收

引數預設值描述
removeAbandonedOnMaintenancefalse

標記是否刪除洩露的連線,如果他們超過了removeAbandonedTimout的限制.如果設定為true, 

連線被認為是被洩露並且可以被刪除,如果空閒時間超過removeAbandonedTimeout. 

設定為true可以為寫法糟糕的沒有關閉連線的程式修復資料庫連線.

dbcp1.X為removeAbandoned

removeAbandonedTimeout300洩露的連線可以被刪除的超時值, 單位秒
logAbandonedfalse

標記當Statement或連線被洩露時是否列印程式的stack traces日誌。

被洩露的Statements和連線的日誌新增在每個連線開啟或者生成新的Statement,

因為需要生成stack trace。


注意:

•Java資料庫連線有“8小時問題”,所以destroy-method="close"一定要加上。“8小時問題”是指一個連線空閒8小時資料庫會自動關閉,而資料來源並不知道。

•高併發下,可以testOnBorrow設定false,testWhileIdle設定為true,這樣就會定時對後臺空連結進行檢測發現無用連線就會清除掉,不會每次都去都去檢測是否8小時的空連結。

4.DBCP2原理

    DBCP2在初始化時會從資料庫獲取指定數量的連線,把這些連線存放到空閒連線佇列LinkedBlockingDeque裡面,這個佇列是雙向鏈路阻塞型佇列,先進先出,每次要使用連線時就從這個佇列獲取頭部結點,獲取連線時使用的鎖是ReentrantLock.獲取到連線時,該連線節點出佇列,更改狀態並且存放到一個ConcurrentHashMap中,標識該連線已被使用,另外會有一個空閒連線檢測執行緒不斷去檢測ConcurrentHashMap中連線的狀態,如果連線已經關閉(不是資料庫連線關閉,而是連線在DBCP連線池中關閉),則把它從ConcurrentHashMap中刪除,並且回收到LinkedBlockingDeque裡面。

5.DBCP2的優缺點

5.1 優點

配置簡單

5.2 缺點

    無論是空閒連線還是已使用的連線,都是存放加鎖的ConcurrentHashMap或LinkedBlockingDeque中,併發量低,效能不好,適用於小型系統。從資料庫獲取連線的過程中還加了synchronized同步鎖,如果網路容易中斷的場景下,一旦與資料庫建立的網路出現問題,容易導致死鎖。

    本人在線上環境的使用情況看,存在連線無法正常關閉的問題,導致連線耗盡丟擲異常,需要配空閒連接回收執行緒去定時回收。