druid return行为方法源码示例解析
序
本文主要研究一下druid的return行为
close
com/alibaba/druid/pool/DruidPooledConnection.java
@Override public void close() throws SQLException { if (this.disable) { return; } DruidConnectionHolder holder = this.holder; if (holder == null) { if (dupCloseLogEnable) { LOG.error("dup close"); } return; } DruidAbstractDataSource dataSource = holder.getDataSource(); boolean isSameThread = this.getOwnerThread() == Thread.currentThread(); if (!isSameThread) { dataSource.setAsyncCloseConnectionEnable(true); } if (dataSource.isAsyncCloseConnectionEnable()) { syncClose(); return; } if (!CLOSING_UPDATER.compareAndSet(this, 0, 1)) { return; } try { for (ConnectionEventListener listener : holder.getConnectionEventListeners()) { listener.connectionClosed(new ConnectionEvent(this)); } List<Filter> filters = dataSource.getProxyFilters(); if (filters.size() > 0) { FilterChainImpl filterChain = new FilterChainImpl(dataSource); filterChain.dataSource_recycle(this); } else { recycle(); } } finally { CLOSING_UPDATER.set(this, 0); } this.disable = true; }
close方法先从holder获取当前的dataSource,然后判断ownerThread,若不是同一个线程则设置asyncCloseConnectionEnable为true,若asyncCloseConnectionEnable为true则执行syncClose(这里语义貌似相反),否则执行recycle方法
syncClose
com/alibaba/druid/pool/DruidPooledConnection.java
public void syncClose() throws SQLException { lock.lock(); try { if (this.disable || CLOSING_UPDATER.get(this) != 0) { return; } DruidConnectionHolder holder = this.holder; if (holder == null) { if (dupCloseLogEnable) { LOG.error("dup close"); } return; } if (!CLOSING_UPDATER.compareAndSet(this, 0, 1)) { return; } for (ConnectionEventListener listener : holder.getConnectionEventListeners()) { listener.connectionClosed(new ConnectionEvent(this)); } DruidAbstractDataSource dataSource = holder.getDataSource(); List<Filter> filters = dataSource.getProxyFilters(); if (filters.size() > 0) { FilterChainImpl filterChain = new FilterChainImpl(dataSource); filterChain.dataSource_recycle(this); } else { recycle(); } this.disable = true; } finally { CLOSING_UPDATER.set(this, 0); lock.unlock(); } }
syncClose方法主要是加锁执行recycle
recycle
public void recycle() throws SQLException { if (this.disable) { return; } DruidConnectionHolder holder = this.holder; if (holder == null) { if (dupCloseLogEnable) { LOG.error("dup close"); } return; } if (!this.abandoned) { DruidAbstractDataSource dataSource = holder.getDataSource(); dataSource.recycle(this); } this.holder = null; conn = null; transactionInfo = null; closed = true; }
recycle方法主要是执行dataSource.recycle(this)
DruidDataSource.recycle
com/alibaba/druid/pool/DruidDataSource.java
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 { // check need to rollback? 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); } } boolean putLast(DruidConnectionHolder e, long lastActiveTimeMillis) { if (poolingCount >= maxActive || e.discard || this.closed) { return false; } e.lastActiveTimeMillis = lastActiveTimeMillis; connections[poolingCount] = e; incrementPoolingCount(); if (poolingCount > poolingPeak) { poolingPeak = poolingCount; poolingPeakTime = lastActiveTimeMillis; } notEmpty.signal(); notEmptySignalCount++; return true; }
recycle方法先执行DruidConnectionHolder的reset方法,之后针对大于等于phyMaxUseCount的场景执行discardConnection;针对testOnReturn为true,则执行testConnectionInternal校验,校验失败则关闭连接;最后加锁执行putLast把连接放回连接池,若归还失败则关闭连接。
小结
close方法先从holder获取当前的dataSource,然后判断ownerThread,若不是同一个线程则设置asyncCloseConnectionEnable为true,若asyncCloseConnectionEnable为true则执行syncClose(这里语义貌似相反),否则执行recycle方法。
以上就是druid return行为源码示例解析的详细内容,更多关于druid return行为的资料请关注脚本之家其它相关文章!
相关文章
Java8 使用CompletableFuture 构建异步应用方式
这篇文章主要介绍了Java8 使用CompletableFuture 构建异步应用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11MyBatis-Plus 分页查询以及自定义sql分页的实现
这篇文章主要介绍了MyBatis-Plus 分页查询以及自定义sql分页的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-08-08spring boot application properties配置实例代码详解
本文通过代码给大家介绍了spring boot application properties配置方法,需要的的朋友参考下吧2017-07-07
最新评论