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

相关推荐
杨云龙UP4 小时前
Oracle 19c 单机到单机 Active Data Guard 搭建与巡检操作手册
数据库·oracle·adg·操作指南·data guard·dg搭建
我科绝伦(Huanhuan Zhou)7 小时前
oracle坏块导致备份不了
数据库·oracle·ffmpeg
杨云龙UP9 小时前
Oracle 19c RAC到RAC Active Data Guard标准搭建与巡检指南
运维·服务器·数据库·oracle·adg·data guard·rac到rac
许彰午9 小时前
06-Oracle卸载与重装完整流程
数据库·oracle
我的xiaodoujiao9 小时前
Django 基础知识详细图文教程 13-Django 模型定义与使用 3
数据库·后端·python·测试工具·oracle·django
我科绝伦(Huanhuan Zhou)9 小时前
oracle RAC共享存储换盘操作指南
数据库·oracle
wangbing112510 小时前
重建oracle服务
数据库·oracle
shaibdoio10 小时前
瞬维AI落地经验:AI Agent工具调用准确率怎么提
数据库·人工智能·oracle
jnrjian1 天前
Oracle Inlist 和exists的最佳执行计划
oracle
许彰午2 天前
01-Oracle数据库简介与版本选择
数据库·oracle