写点什么

druid 源码阅读 10—— 过一下流程图中的 getConnectionDirect

作者:张大彪
  • 2022 年 5 月 20 日
  • 本文字数:890 字

    阅读完需:约 3 分钟

将流程图中的代码串一下,看看 druid 在讲一个什么故事。

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); }}
复制代码

复制代码

三个步骤:

  • 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 对象

用户头像

张大彪

关注

还未添加个人签名 2018.04.25 加入

还未添加个人简介

评论

发布
暂无评论
druid 源码阅读 10—— 过一下流程图中的getConnectionDirect_张大彪_InfoQ写作社区