1、简介
在本文中,我们将了解 com.alibaba.druid.pool.DruidDataSource#getConnection() 方法的执行流程。
2、环境
 os-window10druid-1.2.8jdk-1.8.0_312maven-3.8.1
   复制代码
 3、获取连接流程
1、调用 com.alibaba.druid.pool.DruidDataSource#getConnection(long)重载方法
 @Overridepublic 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);}
   复制代码
 
评论