1、简介
在本文中,我们将了解 com.alibaba.druid.pool.DruidDataSource#getConnection() 方法的执行流程。
2、环境
os-window10
druid-1.2.8
jdk-1.8.0_312
maven-3.8.1
复制代码
3、获取连接流程
1、调用 com.alibaba.druid.pool.DruidDataSource#getConnection(long)重载方法
@Override
public DruidPooledConnection getConnection() throws SQLException {
return getConnection(maxWait);
}
复制代码
2、执行 init()初始化方法,如果 Filter 集合不为空则利用责任链模式执行 Filter 的 dataSource_getConnection 方法。
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
return getConnectionDirect(maxWaitMillis);
}
}
复制代码
3、最后都是执行 com.alibaba.druid.pool.DruidDataSource#getConnectionDirect 方法。getConnectionDirect 代码逻辑如下:
3.1、执行 com.alibaba.druid.pool.DruidDataSource#getConnectionInternal 方法
DruidPooledConnection poolableConnection;
try {
poolableConnection = getConnectionInternal(maxWaitMillis);
} catch (GetConnectionTimeoutException ex) {
if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) {
notFullTimeoutRetryCnt++;
if (LOG.isWarnEnabled()) {
LOG.warn("get connection timeout retry : " + notFullTimeoutRetryCnt);
}
continue;
}
throw ex;
}
复制代码
3.2、testOnBorrow 参数为 true 时检查连接是否可用,不可用的连接进行丢弃处理
if (testOnBorrow) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
}
复制代码
3.3、testOnBorrow 参数为 false 时的执行流程如下:
3.3.1、检查连接是否被关闭
if (poolableConnection.conn.isClosed()) {
discardConnection(poolableConnection.holder); // 传入null,避免重复关闭
continue;
}
复制代码
3.3.2、检查是否配置了 testWhileIdle、removeAbandoned 参数,并根据配置做相应的处理。
if (testWhileIdle) {
final DruidConnectionHolder holder = poolableConnection.holder;
long currentTimeMillis = System.currentTimeMillis();
long lastActiveTimeMillis = holder.lastActiveTimeMillis;
long lastExecTimeMillis = holder.lastExecTimeMillis;
long lastKeepTimeMillis = holder.lastKeepTimeMillis;
if (checkExecuteTime
&& lastExecTimeMillis != lastActiveTimeMillis) {
lastActiveTimeMillis = lastExecTimeMillis;
}
if (lastKeepTimeMillis > lastActiveTimeMillis) {
lastActiveTimeMillis = lastKeepTimeMillis;
}
long idleMillis = currentTimeMillis - lastActiveTimeMillis;
long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
if (timeBetweenEvictionRunsMillis <= 0) {
timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
}
if (idleMillis >= timeBetweenEvictionRunsMillis
|| idleMillis < 0 // unexcepted branch
) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
}
}
}
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();
}
}
复制代码
3.3.3、检查是否默认自动提交
if (!this.defaultAutoCommit) {
poolableConnection.setAutoCommit(false);
}
复制代码
评论