数据库连接池连接超时报错

一、问题原因:

数据库重启数据库空闲连接超过设置的最大timemout时间导致数据库会强行断开已有的链接,就会报这个异常。

如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql就将该连接关闭。这时,你的Java应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就会产生上述错误。一般mysql自身连接的等待时间(wait_timeout)缺省为8小时,或者通过命令参数查看
在这里插入图片描述

二、解决办法

1、重启服务器

重启服务器,数据库连接池就会重新初始化, 重新获取和数据库的有效连接

2、连接池配置

1)数据库连接池增加探活配置(推荐这种方式

为了避免空闲时间过长超过最大空闲时间而被断开,我们在配置数据库连接池的时候需要做一些检查连接有效性的配置,不同连接池可能不同。
以druid为例相关配置,更多配置参考官网:[配置]
(https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8)

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      first:  #数据源1
        url: jdbc:mysql://XXXX:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: test
        password: 282s661234567879WWUr4gS
        initial-size: 10
        max-active: 200
        min-idle: 10
        max-wait: 60000
        pool-prepared-statements: true
        max-pool-prepared-statement-per-connection-size: 20
        time-between-eviction-runs-millis: 60000
        min-evictable-idle-time-millis: 300000
      second:  #数据源2
        url: jdbc:mysql://XXXX:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: test
        password: 282s661234567879WWUr4gS
        initial-size: 10
        max-active: 200
        min-idle: 10
        max-wait: 60000
        pool-prepared-statements: true
        max-pool-prepared-statement-per-connection-size: 20
        #其中timeBetweenEvictionRunsMillis需要小于mysql的wait_timeout。
        time-between-eviction-runs-millis: 60000
        min-evictable-idle-time-millis: 300000
2)增大数据库默认的超时等待时间(wait_timeout)

之前的文章MySQL三大日志及事务隔离级别中讲过两个参数:
interactive_timeout:服务器关闭交互式连接前等待活动的秒数。(eg:客户端连接交互式连接)
wait_timeout:服务器关闭非交互连接之前等待活动的秒数。(eg:jdbc连接)

需要修改global的interactive_timeout参数,wait_timeout也会跟着改,可以真正调整超时时间。

  • Windows下在%MySQL HOME%/bin下有mysql.ini配置文件,需修改配置文件。
  • linux的服务器上的mysql:
    set global interactive_timeout=31536000;(wait_timeout最大为31536000即1年)

注:如果太大,可能导致连接数较多,引起性能下降。

3)JDBC配置Mysql连接URL重连机制

jdbc:mysql://localhost:3306/test?user=root&password=&autoReconnect=true

4)JDBC减少连接池内连接生存周期:使之小于所设置的wait_timeout 的值
### 关于 WebLogic 数据库连接池报错问题 当在 WebLogic 中使用数据库连接池并执行带有 `ROWNUM` 条件的 `UPDATE` 语句时,可能会遇到一些特定的错误。这通常是因为 Oracle 数据库中的 `ROWNUM` 是伪列,在某些情况下无法直接用于更新操作。 以下是可能的原因以及解决方案: #### 原因分析 1. **Oracle ROWNUM 特性** 在 Oracle 中,`ROWNUM` 是一种特殊的伪列,它会在查询结果集中分配序号。然而,由于其计算顺序的关系,`ROWNUM` 可能会限制 SQL 查询的结果范围,从而影响到后续的操作,比如 `UPDATE` 或 `DELETE`[^1]。 2. **WebLogic 连接池配置问题** 如果 WebLogic 配置不当,可能导致事务隔离级别不匹配或者预编译语句缓存失效等问题,进而引发异常行为[^3]。 --- #### 解决方案 ##### 方法一:重构 SQL 逻辑 可以通过子查询的方式重新设计 SQL 语句,使得 `ROWNUM` 能够正常工作。例如: ```sql -- 错误写法 (可能导致失败) UPDATE table_name SET column = value WHERE ROWNUM <= n; -- 正确写法 (通过子查询绕过 ROWNUM 的限制) UPDATE ( SELECT * FROM table_name WHERE condition AND ROWNUM <= n ) t SET t.column = value; ``` 这种方法利用了嵌套子查询来规避 `ROWNUM` 对主表的影响,同时确保只更新符合条件的部分记录[^5]。 --- ##### 方法二:调整 WebLogic 数据源设置 如果问题是由于 WebLogic 数据源配置引起的,则可以尝试以下方法: 1. **启用测试连接功能** 确保数据源启用了 “Test Table” 功能,并设置了合理的验证频率。 2. **修改事务超时时间** 在 WebLogic 控制台中找到对应的数据源,增加事务超时时间(Transaction Timeout),以防止长时间运行的 SQL 导致连接中断。 3. **禁用 PreparedStatement 缓存** 如果怀疑是预编译语句缓存导致的问题,可以在数据源高级属性中关闭此选项: ```properties weblogic.jdbc.pool.StatementCacheSize=0 ``` 这些措施有助于提高连接稳定性,减少潜在的错误发生概率。 --- ##### 方法三:引入第三方连接池替代默认实现 虽然 WebLogic 自带了一个强大的数据库连接池机制,但在复杂场景下仍可能存在局限性。此时可以选择替换为更高效的外部连接池工具,如 HikariCP 或 Druid。例如: ```java @Configuration @EnableTransactionManagement public class DataSourceConfig { @Bean public DataSource dataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); dataSource.setJdbcUrl("jdbc:oracle:thin:@localhost:1521/orcl"); dataSource.setUsername("username"); dataSource.setPassword("password"); return dataSource; } } ``` 上述代码展示了如何使用 Spring Boot 和 HikariCP 替代原生 WebLogic 数据源[^4]。 --- ### 总结 针对 WebLogic 数据库连接池在执行带有 `ROWNUM` 条件的 `UPDATE` 语句时报错的情况,可以从以下几个方面入手解决问题:重写 SQL 结构使其兼容;优化 WebLogic 数据源参数配置;必要时考虑切换至其他高性能连接池组件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只IT攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值