上一篇主要分析了获取连接,本篇分析归还连接与连接清理。归还连接基本上就一个入口:
- 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验证方式是用户指定的用于以空闲连接进行验证策略,意议不大。
本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/1185901