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]