数据源的关闭方法(close)
public void close() {
if (LOG.isInfoEnabled()) {
LOG.info("{dataSource-" + this.getID() + "} closing ...");
}
//获取锁
lock.lock();
try {
//如果已经关闭,则退出
if (this.closed) {
return;
}
//如果还未初始化,则退出
if (!this.inited) {
return;
}
//设置'正在关闭状态' = true
this.closing = true;
//日志线程中断
if (logStatsThread != null) {
logStatsThread.interrupt();
}
//创建连接线程中断
if (createConnectionThread != null) {
createConnectionThread.interrupt();
}
//销毁连接线程中断
if (destroyConnectionThread != null) {
destroyConnectionThread.interrupt();
}
//创建连接调度线程注销
if (createSchedulerFuture != null) {
createSchedulerFuture.cancel(true);
}
//销毁连接调度线程注销
if (destroySchedulerFuture != null) {
destroySchedulerFuture.cancel(true);
}
//循环连接池
for (int i = 0; i < poolingCount; ++i) {
//获取连接
DruidConnectionHolder connHolder = connections[i];
//关闭连接中的Statement
for (PreparedStatementHolder stmtHolder : connHolder.getStatementPool().getMap().values()) {
connHolder.getStatementPool().closeRemovedStatement(stmtHolder);
}
connHolder.getStatementPool().getMap().clear();
Connection physicalConnection = connHolder.getConnection();
//连接关闭
try {
physicalConnection.close();
} catch (Exception ex) {
LOG.warn("close connection error", ex);
}
//连接池设置为空
connections[i] = null;
destroyCountUpdater.incrementAndGet(this);
}
poolingCount = 0;
//注销当前数据源,DruidDataSourceStatManager.removeDataSource(DruidDataSource.this);
unregisterMbean();
enable = false;
//释放所有非空的等待连接(关联takeLast方法)
notEmpty.signalAll();
notEmptySignalCount++;
//关闭成功
this.closed = true;
//记录关闭时间
this.closeTimeMillis = System.currentTimeMillis();
//创建销毁异常
disableException = new DataSourceDisableException();
//关闭过滤器
for (Filter filter : filters) {
filter.destroy();
}
} finally {
this.closing = false;
lock.unlock();
}
if (LOG.isInfoEnabled()) {
LOG.info("{dataSource-" + this.getID() + "} closed");
}
}
回收连接(recycle)
判断当前连接是否需要被回收
protected void recycle(DruidPooledConnection pooledConnection) throws SQLException {
final DruidConnectionHolder holder = pooledConnection.holder;
//连接不存在则退出
if (holder == null) {
LOG.warn("connectionHolder is null");
return;
}
//记录线程不同
if (logDifferentThread //
&& (!isAsyncCloseConnectionEnable()) //
&& pooledConnection.ownerThread != Thread.currentThread()//
) {
LOG.warn("get/close not same thread");
}
final Connection physicalConnection = holder.conn;
//如果开启跟踪
if (pooledConnection.traceEnable) {
Object oldInfo = null;
//获取活跃连接锁
activeConnectionLock.lock();
try {
//这边是双重检查
if (pooledConnection.traceEnable) {
//活跃连接中删除该连接,并将跟踪关闭
oldInfo = activeConnections.remove(pooledConnection);
pooledConnection.traceEnable = false;
}
} finally {
//释放活跃连接锁
activeConnectionLock.unlock();
}
//如果删除失败,则记录
if (oldInfo == null) {
if (LOG.isWarnEnabled()) {
LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
}
}
}
final boolean isAutoCommit = holder.underlyingAutoCommit;
final boolean isReadOnly = holder.underlyingReadOnly;
final boolean testOnReturn = this.testOnReturn;
try {
//如果连接未开启自动提交,未开启只读,则连接回滚
if ((!isAutoCommit) && (!isReadOnly)) {
pooledConnection.rollback();
}
// reset holder, restore default settings, clear warnings
boolean isSameThread = pooledConnection.ownerThread == Thread.currentThread();
if (!isSameThread) {
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
holder.reset();
} finally {
lock.unlock();
}
} else {
holder.reset();
}
if (holder.discard) {
return;
}
//最大使用次数校验
if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
discardConnection(holder);
return;
}
//如果连接已关闭,则计数,结束该程序
if (physicalConnection.isClosed()) {
lock.lock();
try {
if (holder.active) {
activeCount--;
holder.active = false;
}
closeCount++;
} finally {
lock.unlock();
}
return;
}
//连接回收测试
if (testOnReturn) {
boolean validate = testConnectionInternal(holder, physicalConnection);
if (!validate) {
JdbcUtils.close(physicalConnection);
destroyCountUpdater.incrementAndGet(this);
lock.lock();
try {
if (holder.active) {
activeCount--;
holder.active = false;
}
closeCount++;
} finally {
lock.unlock();
}
return;
}
}
if (holder.initSchema != null) {
holder.conn.setSchema(holder.initSchema);
holder.initSchema = null;
}
if (!enable) {
discardConnection(holder);
return;
}
boolean result;
final long currentTimeMillis = System.currentTimeMillis();
//最大连接时间校验
if (phyTimeoutMillis > 0) {
long phyConnectTimeMillis = currentTimeMillis - holder.connectTimeMillis;
if (phyConnectTimeMillis > phyTimeoutMillis) {
discardConnection(holder);
return;
}
}
lock.lock();
try {
//如果连接存活,则进行回收
if (holder.active) {
activeCount--;
holder.active = false;
}
//关闭数加一
closeCount++;
//将连接重新放入池中
result = putLast(holder, currentTimeMillis);
recycleCount++;
} finally {
lock.unlock();
}
//如果连接放入失败,则关闭当前连接
if (!result) {
JdbcUtils.close(holder.conn);
LOG.info("connection recyle failed.");
}
} catch (Throwable e) {
//发生异常则清除执行语句,并且连接未关闭,则关闭该连接。
holder.clearStatementCache();
if (!holder.discard) {
discardConnection(holder);
holder.discard = true;
}
LOG.error("recyle error", e);
recycleErrorCountUpdater.incrementAndGet(this);
}
}