dynamic动态数据源+druid阿里连接池设置oracle.net.CONNECT_TIMEOUT失效的问题

本文由个人总结,如需转载使用请标明原著及原文地址

dynamic动态数据源+druid阿里连接池设置oracle.net.CONNECT_TIMEOUT失效的问题

dynamic动态数据源 oracle 出现socket read time out

出现问题的版本

bash 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.5.8</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.20</version>
</dependency>

在这版本下url: jdbc:oracle:thin:@//ip:1521/ORCL?oracle.net.CONNECT_TIMEOUT=60000配置不生效,直接说解决方案,如果有兴趣的话后面有排错过程

解决方案

将dynamic-datasource-spring-boot-starter的版本升到3.6.0以上,然后修改配置文件

注意,connect-timeout和socket-timeout都要配置,不然会报错

bash 复制代码
spring:
  datasource:
    dynamic:
      primary: master
      datasource:
        master:
          driver-class-name: oracle.jdbc.OracleDriver
          url: jdbc:oracle:thin:@//ip:1521/ORCL
          username: xxx
          password: xxx
          type: com.alibaba.druid.pool.DruidDataSource
          druid:
            connect-timeout: 60000
            socket-timeout: 60000

排错过程

DruidDataSourceCreator

DruidDataSourceCreator是dynamic中创建阿里连接池的类

可以看到,他在这设置了一些参数,然后调用了dataSource.init()

3.5.8版本的dynamic在这并没有设置connect-timeout和socket-timeout,所以无论你配置文件怎么配置,DruidDataSource的connect-timeout和socket-timeout都是0,接下来到了dataSource.init()里

DruidDataSource

DruidDataSource是阿里连接池的数据源,是com.alibaba.druid里的类

在init方法中,给connectTimeout和socketTimeout设置值的是红框的部分代码。由于DruidDataSourceCreator里没有调用DruidDataSource的setConnectTimeout和setSocketTimeout方法,所以connectTimeout和socketTimeout都是0。

此时connectTimeout和socketTimeout都会被设置为10000

initFromUrlOrProperties方法中也会修改connectTimeout和socketTimeout的值,但是只对mysql有效。mysql类型的数据源会从jdbcurl中读取connectTimeout和socketTimeout参数,也会从connectProperties里读取connectTimeout和socketTimeout参数但是前提是,你是mysql!!!!!oracle他没做任何操作!!!!!

所以此时connectTimeout和socketTimeout依旧都是10000,后续代码中没有再对connectTimeout和socketTimeout进行修改

init方法执行完成时connectTimeout和socketTimeout为10000

DruidAbstractDataSource

DruidAbstractDataSource是DruidDataSource继承的类,在执行sql前会调用createPhysicalConnection方法获取数据库连接

上一步我们知道创建出来的DruidDataSource的connectTimeout和socketTimeout都是10000,所以会进入上图代码里。

connectTimeoutStr在DruidDataSourceCreator中也没设置,所以是null

connectTimeoutStr会被设置为Integer.toString(this.connectTimeout)也就是10000

然后最坑的来了createPhysicalConnection方法里执行了physicalConnectProperties.put("oracle.net.CONNECT_TIMEOUT", this.connectTimeoutStr);把我们url上的oracle.net.CONNECT_TIMEOUT给覆盖了

所以不论你jdbcurl上怎么设置oracle.net.CONNECT_TIMEOUT属性,连接超时都会是10秒

dynamic创建DruidDataSource时,没有调用DruidDataSource的setConnectTimeout和setSocketTimeout方法

DruidDataSource自己又没有针对oracle的对connectTimeout和socketTimeout进行赋值

所以无论你怎么配置,创建出来的oracle数据源超时时间都是10秒

dynamic3.6.0

在3.6.0版本中支持了DruidDataSourceCreator的doCreateDataSource的setParam方法中,读取connectTimeout和socketTimeout字段对DruidDataSource进行赋值,所以升级版本后可以解决

旁门左道的方法

在不改变版本的情况下,我试过用自定义filter调用DruidDataSource的setConnectTimeout成功修改了dynamic+druid+oracle连接超时时间

代码我删了就不截图了

创建个filter继承阿里的FilterAdapter,加上@component

然后在配置文件里在filters里加上全路径类名

bash 复制代码
spring:
  datasource:
    dynamic:
      primary: master
      datasource:
        master:
          driver-class-name: oracle.jdbc.OracleDriver
          url: jdbc:oracle:thin:@//ip:1521/ORCL
          username: xxx
          password: xxx
          type: com.alibaba.druid.pool.DruidDataSource
          druid:
            filters: stat,com.xxx.DruidCustomerFilter

init方法入参是DataSourceProxy实际入参是DruidDataSource,DruidDataSource有实现DataSourceProxy接口,可以把DataSourceProxy的dataSource强转成DruidDataSource然后调用setConnectTimeout方法,就能修改connectTimeout的值了

相关推荐
Lucifer三思而后行1 小时前
一次 Oracle RAC 归档告警排查
数据库·oracle
Lucifer三思而后行3 小时前
Vertica 玩转示例数据库:VMart
数据库·oracle
Lucifer三思而后行3 小时前
zCloud 纳管 Oracle 数据库
数据库·oracle
cyber_两只龙宝3 小时前
【Oracle】Oracle之SQL的转换函数和条件表达式
linux·运维·数据库·sql·云原生·oracle
Lucifer三思而后行3 小时前
中国移动 BCLinux 8.8 一键安装 Oracle 26ai
数据库·oracle
jnrjian3 小时前
DR$ JSON_INDEX $DG表的处理 Json search index data guide
oracle·json
cyber_两只龙宝4 小时前
【Oracle】Oracle之SQL的聚合函数和分组
linux·运维·数据库·sql·云原生·oracle
杨云龙UP5 小时前
2000—CentOS Linux 7上部署Oracle 19c(19.3) RAC(RedHat/CentOS 7/8)
linux·运维·服务器·数据库·oracle·centos
懒铭心5 小时前
RHEL 6.10 + Oracle 11.2.0.4 RAC 高可用集群部署指南
oracle
Yushan Bai8 小时前
ORACLE报错ORA-04030 koh-kghu sessi,pmucalm coll的分析处理步骤
数据库·oracle