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

相关推荐
海鸥-w14 小时前
数据库冗余字段设计笔记
java·数据库·笔记·oracle
实泽有之,无泽虚之16 小时前
ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务问题原因及解决办法
数据库·oracle
程序员塔塔喵17 小时前
【MySQL篇|第十篇】深分页问题
数据库·oracle·深分页问题
qq_4523962318 小时前
第八篇:《VACUUM、自动清理与膨胀治理》
jvm·数据库·oracle
晴天¥19 小时前
记录Oracle11g数据库OGG同步实验
oracle·oracle ogg·oracle高可用架构
晴天¥19 小时前
Oracle集群中是该如何管理控制文件和日志文件组?
数据库·oracle
云策数链20 小时前
用友 T+Cloud / U8 项目交接时的账套健康度核查清单
数据库·oracle·erp·用友·云策数链
jnrjian20 小时前
Oracle RAC crs stop时force 关闭DB,另一个node会立即进行recover
数据库·oracle
次次皮20 小时前
Oracle判空踩坑(对比mysql)
数据库·mysql·oracle
znnnk1 天前
数据库被AI“重写”:2026,从CPU中心走向GPU中心
数据库·人工智能·oracle