removeAbandoned参数指定连接池是否移除被遗弃的连贯。
具体的逻辑分两局部:一部分是设置流动连贯、筹备未来判断是否应该被遗弃,这个动作是在getConnection获取连贯后执行的;另外一部分是在连贯回收工作DestroyTask中,咱们在剖析连贯回收的文章中疏忽了这部分内容,明天补充一下。
getConnection办法获取连贯之后判断removeAbandoned参数关上的话,就设置以后连贯的connectedTimeNano为零碎工夫,而后将以后连贯放入activeConnections中,筹备被回收线程查看、移除。
代码在getConnectionDirect中:
if (removeAbandoned) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); poolableConnection.connectStackTrace = stackTrace; poolableConnection.setConnectedTimeNano(); poolableConnection.traceEnable = true; activeConnectionLock.lock(); try { activeConnections.put(poolableConnection, PRESENT); } finally { activeConnectionLock.unlock(); } }
第二局部须要回顾一下上一篇文章中的DestroyTask的run办法,在调用shrink之后判断RemoveAbandoned则调用removeAbandoned()办法:
@Override public void run() { shrink(true, keepAlive); if (isRemoveAbandoned()) { removeAbandoned(); } }
removeAbandoned办法源码,分段贴出:
public int removeAbandoned() { int removeCount = 0; long currrentNanos = System.nanoTime(); List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>(); activeConnectionLock.lock(); try { Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator(); for (; iter.hasNext();) { DruidPooledConnection pooledConnection = iter.next(); if (pooledConnection.isRunning()) { continue; } long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000); if (timeMillis >= removeAbandonedTimeoutMillis) { iter.remove(); pooledConnection.setTraceEnable(false); abandonedList.add(pooledConnection); } } } finally { activeConnectionLock.unlock(); }
首先activeConnectionLock加锁。
循环查看activeConnections中的每一个连贯。
如果连贯isRunning()的话,则不解决以后连贯。连贯的running状态是在连贯执行sql语句前调用beforeExecute办法设置为true、执行实现后调用afterExecute办法设置为false的。也就是说running状态其实就是字面意思,如果一个连贯正在执行sql语句,running为true,执行实现后,running为false。
计算timeMillis为连贯获取之后到当初的时长,留神connectedTimeNano是在咱们下面所说的第一步:连贯获取之后设置的。
如果timeMillis大于参数设定的移除时长removeAbandonedTimeoutMillis的话,则连贯放入abandonedList中筹备移除。
之后,开释activeConnectionLock锁。
前面的代码就不贴出了,很简略,就是从abandonedList列表中一一取出连贯,敞开连贯,标记以后连贯的abandoned=true。
总结
联合Druid连接池的连贯偿还过程,总结一下removeAbandoned参数的总体应用逻辑:
- removeAbandoned参数设置为true的话,须要配合设置一个removeAbandonedTimeoutMillis,认定连贯被遗弃的时长
- 从连贯给获取到开始计时,并将连贯放入到流动连贯activeConnections中
- 连贯在执行sql语句过程中(running状态)不会被认定为遗弃而回收
- 连贯执行实现、偿还到连接池的时候,如果还没有被认定为遗弃,则从activeConnections中移除(平安了...)
- 连贯尚未归还给连接池、也不在running状态的状况下(比方利用在执行完sql语句之后不close连贯的状况下),连贯回收线程查看该连贯自从被getConnection获取之后到当初的时长如果大于removeAbandonedTimeoutMillis的话,就会给该连贯打标记:须要被遗弃。并敞开该连贯,不再容许其偿还到连接池
无关removeAbandoned参数,在初始化过程中的initCheck()办法中有一段代码:
if (removeAbandoned) { LOG.warn("removeAbandoned is true, not use in production."); }
意思很明确,removeAbandoned参数并不是用在生产环境中的,是专为测试环境筹备的参数。因而,倡议大家开发过程中罗唆遗记这个参数,不要设置为关上。
上一篇 连接池 Druid (四) - 连贯偿还