数据库连接池druid断开重连

使用数据库连接池druid,需要在与数据库断开时重新连接,可对com.alibaba.druid.pool.DruidDataSource的属性进行设置。
有如下两种设置方式:
1、每次检查数据库连接: testOnBorrow设置为true(注意大并发可能会有性能问题)。
2、闲时检查数据库连接:testOnBorrow设置为false,testWhileIdle设置为true,闲置时间大于timeBetweenEvictionRunsMillis即可重连。

相关源码(DruidDataSource.java)如下:
public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
    int notFullTimeoutRetryCnt = 0;
    for (;;) {
        // handle notFullTimeoutRetry
        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;
        }

        if (testOnBorrow) {
            boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
            if (!validate) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("skip not validate connection.");
                }

                Connection realConnection = poolableConnection.conn;
                discardConnection(realConnection);
                continue;
            }
        } else {
            Connection realConnection = poolableConnection.conn;
            if (poolableConnection.conn.isClosed()) {
                discardConnection(null); // 传入null,避免重复关闭
                continue;
            }

            if (testWhileIdle) {
                long currentTimeMillis             = System.currentTimeMillis();
                long lastActiveTimeMillis          = poolableConnection.holder.lastActiveTimeMillis;
                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(realConnection);
                         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();
            }
        }

        if (!this.defaultAutoCommit) {
            poolableConnection.setAutoCommit(false);
        }

        return poolableConnection;
    }
}
原文地址:https://www.cnblogs.com/MrHacker/p/14121660.html