alibaba / druid

阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
https://github.com/alibaba/druid/wiki
Apache License 2.0
27.95k stars 8.58k forks source link

druid 1.2.20在Oracle数据库上socketTimeout配置和connectProperties配置无效 #5565

Closed zhl19911203 closed 10 months ago

zhl19911203 commented 10 months ago

druid 1.2.20在Oracle数据库上socketTimeout配置和connectProperties配置无效,怎么在application.yml中配置这个参数,我看默认10s

zrlw commented 10 months ago

需要自己用xml方式配置bean

lizongbo commented 10 months ago

我没有用过yml配置方式 这两个属性本质就是DruidAbstractDataSource的成员变量。

application.properties应该是类似这样配置,你参考验证一下

spring.datasource.druid.connect-timeout=30000 spring.datasource.druid.socket-timeout=30000

lizongbo commented 10 months ago

搜索了一下,应该是配置connectionProperties来控制

LinHuiG commented 9 months ago

我测了一下,druid版本不动,ojdbc版本用ojdbc8 12.2.0.1则socketTimeout有效,oracle.jdbc.ReadTimeout无效 如果用ojdbc6 11.2.0.4.0-atlassian-hosted则需要用connectionProperties=oracle.net.CONNECT_TIMEOUT=6000;oracle.jdbc.ReadTimeout=6000方式才行,socketTimeout无效 这个是druid做了兼容性处理吗

zrlw commented 9 months ago

druid目前只是对oracle.net.CONNECT_TIMEOUT做了处理:

            } else if (isOracle) {
                if (connectTimeoutStr == null) {
                    connectTimeoutStr = Integer.toString(connectTimeout);
                }

                physicalConnectProperties.put("oracle.net.CONNECT_TIMEOUT", connectTimeoutStr);

上面这些代码就不应该存在,数据库类型加版本组合的结果太多了,druid根据数据库类型和版本去设置特定参数的处理方式注定不可持续,特定参数都应该都通过connectionProperties配置,druid将这些参数直接透传给数据库驱动,不应该由druid去判断解析。 配置connectionProperties要看驱动文档,不同版本支持配置的参数名称可能都不一样。

LinHuiG commented 9 months ago

druid目前只是对oracle.net.CONNECT_TIMEOUT做了处理:

            } else if (isOracle) {
                if (connectTimeoutStr == null) {
                    connectTimeoutStr = Integer.toString(connectTimeout);
                }

                physicalConnectProperties.put("oracle.net.CONNECT_TIMEOUT", connectTimeoutStr);

上面这些代码就不应该存在,数据库类型加版本组合的结果太多了,druid根据数据库类型和版本去设置特定参数的处理方式注定不可持续,特定参数都应该都通过connectionProperties配置,druid将这些参数直接透传给数据库驱动,不应该由druid去判断解析。 配置connectionProperties要看驱动文档,不同版本支持配置的参数名称可能都不一样。

我断点进去看了,properties最终是包含oracle.jdbc.ReadTimeout参数的(断点位置在oracle.jdbc.driver.OracleDriver::connect方法入口),但通过druid配置的就不生效,而通过jdbc直接配置的会生效~

不同版本组合的结果有点不太一样 druid1.2.8版本+ojdbc6时,oracle.jdbc.ReadTimeout有效,无setSocketTimeout(1.2.12版本才有) druid1.2.18版本+ojdbc6时,oracle.jdbc.ReadTimeout有效,setSocketTimeout方法无效 druid1.2.18+ojdbc8时,oracle.jdbc.ReadTimeout失效,setSocketTimeout方法有效 当我单独使用ojdbc8时,oracle.jdbc.ReadTimeout有效

zrlw commented 9 months ago

断点打在DruidAbstractDataSource#createPhysicalConnection吧,createPhysicalConnection的入参info里应该有对应的配置,这里面的所有参数都是直接透传给驱动的,除非connectionProperties配置的参数和驱动不一致,否则不应该不支持:

Connection rawConn = getDriver().connect(url, info);
zrlw commented 9 months ago

用开源软件要自己看代码的,升版本前也要比较不同版本的代码差异。 开源软件并不是商业软件,有问题基本上要自己抗,只靠社区是会掉坑里的。

zrlw commented 9 months ago

比如读超时,oracle有的版本使用的参数名是 oracle.net.READ_TIMEOUT,有的版本用的是 oracle.jdbc.ReadTimeout,如果懒得去查找oracle文档,至少要反编译驱动jar包,看一下自己用的驱动包里面OracleConnection定义的参数名是什么吧。

zrlw commented 9 months ago

druid当前master版本只支持mysql和mariadb在jdbc url里配connectTimeout和socketTimeout参数。

DruidDataSource.java
private void initFromUrlOrProperties() {
    if (isMysqlOrMariaDBUrl(jdbcUrl)) { // 这个限定条件有点多余,connectTimeout和socketTimeout这两参数应该不限数据库类型,即使数据库对应的参数名不同,也可以由createPhysicalConnection方法依据数据库类型进行区分设置。