rule 发表于 2018-11-29 10:37:08

Tomcat JDBC pool源码部析 (2)

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


[*]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)关闭该连接。
获取当前连接的锁,从繁忙队列中移除该连接。放入空闲队列中以备其他请求使用。有以下几种情况,该连接会直接关闭,而非放入空闲队列。
1.   从繁忙队列中移除该连接时失败。(此现象很少见)
2.   空闲连接数大小允许的最大空闲连接数,且没有启用空闲连接清理器。
3.   放入空闲队列失败。(与1比较类似,比较少见)
可以看出归还连接比较简单。
对于连接清理,连接池提供了一个Timer来完成:
class PoolCleaner extends TimerTask
该Timer主要清理三个方面的连接。
1.   需要丢弃的连接,从繁忙队列清除。
这类连接主要是长期没有归还的连接。连接池提供了两个时间值:AbandonTimeout和SuspectTimeout。对于超过AbandonTimeout连接,如果Pool当前符合清理Abandon连接的条件,则执行关闭。
对于大于的SuspectTimeout的连接,输出日志提醒。
2.   空闲的连接,从空闲队列中清除。
关闭空闲时间过长的连接,没什么好说的。
3.   对空闲连接进行验证(如果),验证失败的连接。
   VALIDATE_IDLE验证方式是用户指定的用于以空闲连接进行验证策略,意议不大。



页: [1]
查看完整版本: Tomcat JDBC pool源码部析 (2)