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的值了

相关推荐
听雪楼主.2 小时前
某客户系统Oracle数据运行慢分析
数据库·oracle
江畔柳前堤3 小时前
XZ07_解决WORD中间单词间隔过大的问题
数据库·人工智能·线性代数·oracle·数据挖掘·word
小哥哥咯11 小时前
Oracle 19c 与 MySQL 8.0 字符串数据类型对比
mysql·oracle
远方160911 小时前
116-Oracle 26ai 断言(assertion)新特性
大数据·数据库·sql·oracle·database·ai编程
05大叔12 小时前
mysql 触发器,锁
数据库·mysql·oracle
大鹏说大话12 小时前
拒绝“慢查询”:SQL性能优化实战与索引的双刃剑效应
数据库·oracle
jnrjian12 小时前
Oracle documentation bug SSL Version 1.2
oracle
jnrjian14 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle
TTc_14 天前
oracle中的union和union all有什么区别?
数据库·oracle