上一篇主要分析了獲取鏈接,本篇分析歸還鏈接與鏈接清理。歸還鏈接基本上就一個入口:ide
- protected void returnConnection(PooledConnection con) {
- if (isClosed()) {
- //if the connection pool is closed
- //close the connection instead of returning it
- release(con);
- return;
- } //end if
- if (con != null) {
- try {
- con.lock();
- if (busy.remove(con)) {
- if (!shouldClose(con,PooledConnection.VALIDATE_RETURN)) {
- con.setStackTrace(null);
- con.setTimestamp(System.currentTimeMillis());
- if (((idle.size()>=poolProperties.getMaxIdle()) && !poolProperties.isPoolSweeperEnabled()) || (!idle.offer(con))) {
- if (log.isDebugEnabled()) {
- log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle["+idle.size()+"]>=maxIdle["+poolProperties.getMaxIdle()+"] idle.offer failed.");
- }
- release(con);
- }
- } else {
- if (log.isDebugEnabled()) {
- log.debug("Connection ["+con+"] will be closed and not returned to the pool.");
- }
- release(con);
- } //end if
- } else {
- if (log.isDebugEnabled()) {
- log.debug("Connection ["+con+"] will be closed and not returned to the pool, busy.remove failed.");
- }
- release(con);
- }
- } finally {
- con.unlock();
- }
- } //end if
- } //
先看鏈接池有沒有關閉,若是在關閉狀態,則調用release(con)關閉該鏈接。spa
獲取當前鏈接的鎖,從繁忙隊列中移除該鏈接。放入空閒隊列中以備其餘請求使用。有如下幾種狀況,該鏈接會直接關閉,而非放入空閒隊列。debug
1. 從繁忙隊列中移除該鏈接時失敗。(此現象不多見)日誌
2. 空閒鏈接數大小容許的最大空閒鏈接數,且沒有啓用空閒鏈接清理器。orm
3. 放入空閒隊列失敗。(與1比較相似,比較少見)隊列
能夠看出歸還鏈接比較簡單。ci
對於鏈接清理,鏈接池提供了一個Timer來完成:rem
class PoolCleaner extends TimerTaskget
該Timer主要清理三個方面的鏈接。string
1. 須要丟棄的鏈接,從繁忙隊列清除。
這類鏈接主要是長期沒有歸還的鏈接。鏈接池提供了兩個時間值:AbandonTimeout和SuspectTimeout。對於超過AbandonTimeout鏈接,若是Pool當前符合清理Abandon鏈接的條件,則執行關閉。
對於大於的SuspectTimeout的鏈接,輸出日誌提醒。
2. 空閒的鏈接,從空閒隊列中清除。
關閉空閒時間過長的鏈接,沒什麼好說的。
3. 對空閒鏈接進行驗證(若是),驗證失敗的鏈接。
VALIDATE_IDLE驗證方式是用戶指定的用於以空閒鏈接進行驗證策略,意議不大。