druid 源码阅读 10—— 过一下流程图中的 getConnectionDirect
将流程图中的代码串一下,看看 druid 在讲一个什么故事。
复制代码
三个步骤:
init() 初始化连接池
遍历 FilterChain,调用 filterChain.dataSource_connect(this, maxWaitMillis), 这不是研究重点,不展开。
getConnectionDirect(maxWaitMillis)来活的真正的连接对象。
上次我们过了 init(),这次过一下 getConnectionDirect。
1、一个常规的重试逻辑,重试几次,尝试获取连接。
阶段 1:探活检测
判断 testOnBorrow 开关是否打开?
1、是:调用 testConnectioninternal(DruidPolledConnection)方法来测试连接的合法性,即与连接池中的连接对应的数据库的物理长连接是否连通?
是:说明这个链接当前是个有效的活连接,如果马上用的话应该没问题,时间长了就不确定了。
否:丢弃这个链接,拿一个新的。
2、否:判断获得的连接对象是否是 isClosed 状态?
是:丢弃这个链接,拿一个新的。
否:判断 testWhileIdle 开关是否打开?
是:从 pooledconnection.holder 转为 DruidConnectionHolder。检查 3 个值 lastActiveTimeMillis, lastExecTimeMillis, lastKeepTimeMillis
判断该连接距离上次被使用的时间,和 druid 的连接探活检测时间比较,如果该连接距离上次使用的时间> 连接探活检测时间,说明整个连接已经好久没备用了,且过了探活监测时间,不知道是不是活的,需要检测
否:不管这个连接是死是活,都去阶段二
阶段二:构造从连接池返回的连接
判断 removeAbandoned 开关是否打开,是的话,把当前线程的 stackTrace 设置到返回的连接对象,activeConnectinLock.lock()
把当前连接对象放入 activeConnections Map 中,其中 key 为连接对象,value 为 new Object()
activeConnectinLock.unlock()
判断 defaultAutoCommit 开关是否打开?如果没有的话,将当前连接的 autoCommit 属性设为 false。
最终,返回 DruidPolledConnection 对象
评论