写点什么

数据库连接池 -Druid 源码学习(九)

作者:wjchenge
  • 2022 年 5 月 19 日
  • 本文字数:1664 字

    阅读完需:约 5 分钟

1、简介

在本文中,我们将总结 testOnBorrow、testOnReturn、testWhileIdle 的异同。

2、环境

os-window10druid-1.2.8jdk-1.8.0_312maven-3.8.1
复制代码

3、参数含义


testOnBorrow: 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。


testOnReturn: 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。


testWhileIdle: 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。


以上解释来源:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8


其中文档可能一直没更新,关于其中 testOnBorrow、testWhileIdle 的默认值说明有与源码不符的部分如下:


testOnBorrow :文档默认值 true, 源码默认值 false

testWhileIdle :文档默认值 false, 源码默认值 true




关于 validationQuery 参数文档与源码的差异部分:



关于其中 validationQuery 为 null, testOnBorrow、testOnReturn、testWhileIdle 都不会起作用。的描述,通过源码分析,这句话并不完全正确,其中在 init() 方法中关于这几个参数的验证方法为 validationQueryCheck(),而在这个方法之前还执行了一个关键方法 initValidConnectionChecker()。

字面意思是初始化验证连接的检查器,源代码如下:

private void initValidConnectionChecker() {  if (this.validConnectionChecker != null) {    return;  }
String realDriverClassName = driver.getClass().getName(); // mysql 的检查器 if (JdbcUtils.isMySqlDriver(realDriverClassName)) { this.validConnectionChecker = new MySqlValidConnectionChecker();
// oracle 的检查器 } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER) || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) { this.validConnectionChecker = new OracleValidConnectionChecker();
// sql_server 的检查器 } else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER) || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4) || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) { this.validConnectionChecker = new MSSQLValidConnectionChecker();
// PostgreSql 的检查器 } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER) || realDriverClassName.equals(JdbcConstants.ENTERPRISEDB_DRIVER) || realDriverClassName.equals(JdbcConstants.POLARDB_DRIVER)) { this.validConnectionChecker = new PGValidConnectionChecker(); }}
复制代码


validationQueryCheck() 源码如下,主要是验证 testOnBorrow 、 testOnReturn 、 testWhileIdle 配置了 true, validationQuery 为 null, 则会打印错误信息: validationQuery not set 。 其中如果 validConnectionChecker != null 则不会进行这些验证。


private void validationQueryCheck() {  // testOnBorrow 、 testOnReturn 、 testWhileIdle 参数都为 false 则 return  if (!(testOnBorrow || testOnReturn || testWhileIdle)) {    return;  }
// validConnectionChecker 存在则 return if (this.validConnectionChecker != null) { return; }
// validationQuery 参数不为空则 return if (this.validationQuery != null && this.validationQuery.length() > 0) { return; }
String errorMessage = "";
if (testOnBorrow) { errorMessage += "testOnBorrow is true, "; }
if (testOnReturn) { errorMessage += "testOnReturn is true, "; }
if (testWhileIdle) { errorMessage += "testWhileIdle is true, "; }
LOG.error(errorMessage + "validationQuery not set");}
复制代码


发布于: 刚刚阅读数: 3
用户头像

wjchenge

关注

还未添加个人签名 2018.07.27 加入

还未添加个人简介

评论

发布
暂无评论
数据库连接池 -Druid 源码学习(九)_Druid_wjchenge_InfoQ写作社区