Tomcat JDBC pool源码部析 (2)

上一篇主要分析了获取连接,本篇分析归还连接与连接清理。归还连接基本上就一个入口:


  1. protected void returnConnection(PooledConnection con) { 
  2.        if (isClosed()) { 
  3.            //if the connection pool is closed 
  4.            //close the connection instead of returning it 
  5.            release(con); 
  6.            return
  7.        } //end if 
  8.  
  9.        if (con != null) { 
  10.            try { 
  11.                con.lock(); 
  12.  
  13.                if (busy.remove(con)) { 
  14.  
  15.                    if (!shouldClose(con,PooledConnection.VALIDATE_RETURN)) { 
  16.                        con.setStackTrace(null); 
  17.                        con.setTimestamp(System.currentTimeMillis()); 
  18.                        if (((idle.size()>=poolProperties.getMaxIdle()) && !poolProperties.isPoolSweeperEnabled()) || (!idle.offer(con))) { 
  19.                            if (log.isDebugEnabled()) { 
  20.                                log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle["+idle.size()+"]>=maxIdle["+poolProperties.getMaxIdle()+"] idle.offer failed."); 
  21.                            } 
  22.                            release(con); 
  23.                        } 
  24.                    } else { 
  25.                        if (log.isDebugEnabled()) { 
  26.                            log.debug("Connection ["+con+"] will be closed and not returned to the pool."); 
  27.                        } 
  28.                        release(con); 
  29.                    } //end if 
  30.                } else { 
  31.                    if (log.isDebugEnabled()) { 
  32.                        log.debug("Connection ["+con+"] will be closed and not returned to the pool, busy.remove failed."); 
  33.                    } 
  34.                    release(con); 
  35.                } 
  36.            } finally { 
  37.                con.unlock(); 
  38.            } 
  39.        } //end if 
  40.    } // 

先看连接池有没有关闭,如果在关闭状态,则调用release(con)关闭该连接。

获取当前连接的锁,从繁忙队列中移除该连接。放入空闲队列中以备其他请求使用。有以下几种情况,该连接会直接关闭,而非放入空闲队列。

1.     从繁忙队列中移除该连接时失败。(此现象很少见)

2.     空闲连接数大小允许的最大空闲连接数,且没有启用空闲连接清理器。

3.     放入空闲队列失败。(与1比较类似,比较少见)

可以看出归还连接比较简单。

对于连接清理,连接池提供了一个Timer来完成:

class PoolCleaner extends TimerTask

Timer主要清理三个方面的连接。

1.     需要丢弃的连接,从繁忙队列清除。

这类连接主要是长期没有归还的连接。连接池提供了两个时间值:AbandonTimeoutSuspectTimeout。对于超过AbandonTimeout连接,如果Pool当前符合清理Abandon连接的条件,则执行关闭。

对于大于的SuspectTimeout的连接,输出日志提醒。

2.     空闲的连接,从空闲队列中清除。

关闭空闲时间过长的连接,没什么好说的。

3.     对空闲连接进行验证(如果),验证失败的连接。

   VALIDATE_IDLE验证方式是用户指定的用于以空闲连接进行验证策略,意议不大。


本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/1185901

上一篇:工具解析篇:高效利用JS加载.Net程序


下一篇:【死磕JDK源码】ThreadPoolExecutor源码保姆级详解(下)