You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HikariCP连接超时问题:请求超时30003ms,连接池耗尽

解决HikariCP连接池耗尽:Connection is not available超时问题

根据你描述的情况——处理10个及以上表单时连接数持续增长到上限,即便确认连接已关闭仍出现超时,结合你的环境和配置,我整理了几个最可能的原因和对应的排查/解决步骤:

1. 确认是否存在连接泄漏(最常见原因)

你已经设置了leakDetectionThreshold=30000(30秒),HikariCP会在连接超过这个时间未归还时记录泄漏日志。先检查你的应用日志,是否有类似以下的条目:

Connection leak detection triggered for connection com.mysql.jdbc.JDBC4Connection@xxxxxx, stack trace follows...

如果有,说明确实存在连接未被正确释放的情况。此时需要重点排查代码中的资源释放逻辑:

  • 必须确保所有数据库资源在finally块中关闭:Connection、Statement、ResultSet都要在finally里关闭,避免异常导致资源泄漏。示例:
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        conn = dataSource.getConnection();
        pstmt = conn.prepareStatement("SELECT ...");
        rs = pstmt.executeQuery();
        // 业务逻辑处理
    } catch (SQLException e) {
        // 异常处理
    } finally {
        // 按逆序关闭资源,每个关闭操作单独捕获异常避免影响后续关闭
        if (rs != null) try { rs.close(); } catch (SQLException ignored) {}
        if (pstmt != null) try { pstmt.close(); } catch (SQLException ignored) {}
        if (conn != null) try { conn.close(); } catch (SQLException ignored) {}
    }
    
  • 优先使用try-with-resources语法(JDK8支持):它会自动关闭实现了AutoCloseable接口的资源,避免手动关闭遗漏:
    try (Connection conn = dataSource.getConnection();
         PreparedStatement pstmt = conn.prepareStatement("SELECT ...");
         ResultSet rs = pstmt.executeQuery()) {
        // 业务逻辑处理
    } catch (SQLException e) {
        // 异常处理
    }
    

2. 检查事务是否未正确提交/回滚

你的HikariCP配置autoCommit=true,但如果代码中手动开启了事务(conn.setAutoCommit(false)),却没有在finally中提交或回滚,连接会被一直占用:

Connection conn = null;
try {
    conn = dataSource.getConnection();
    conn.setAutoCommit(false);
    // 执行多步数据库操作
    conn.commit(); // 提交事务
} catch (SQLException e) {
    if (conn != null) {
        try { conn.rollback(); } catch (SQLException ignored) {} // 回滚事务
    }
    throw e;
} finally {
    if (conn != null) {
        try { conn.setAutoCommit(true); } catch (SQLException ignored) {} // 恢复自动提交
        try { conn.close(); } catch (SQLException ignored) {} // 关闭连接
    }
}

如果遗漏了commit()或rollback(),连接会保持在事务状态,无法被连接池回收。

3. 排查JSP中的数据库操作逻辑

从错误栈看,连接是在JSP页面(utilBillParaList_jsp)中获取的。JSP属于视图层,直接在这里操作数据库是不规范的,而且JSP的生命周期管理容易导致资源泄漏——比如页面跳转、异常抛出时,finally块可能无法执行。

建议:

  • 将所有数据库操作迁移到Service层,用分层架构隔离数据访问逻辑;
  • 借助Spring等框架的事务管理和连接池自动管理能力,避免手动操作连接。

4. 配置优化与版本升级

  • 临时调大连接池上限:可以先把maximumPoolSize从10调整到更大的值(比如20),验证是否是连接池容量不足导致的问题,但这只是临时方案,必须找到根本原因;
  • 升级HikariCP版本:你使用的2.5.1是2017年的旧版本,存在不少已知的连接管理bug。建议升级到最新的稳定版本(比如4.0.3或更高),新版本修复了很多泄漏检测和连接回收的问题;
  • 匹配MySQL的wait_timeout:你的maxLifetime=1800000(30分钟),MySQL默认的wait_timeout是8小时(28800秒),虽然这不是当前问题的直接原因,但为了避免MySQL主动断开连接导致HikariCP持有无效连接,建议将maxLifetime设置为小于MySQLwait_timeout的值(比如25分钟=1500000毫秒)。

5. 验证MySQL端的连接状态

登录MySQL执行SHOW PROCESSLIST;,查看当前连接的状态:

  • 如果大量连接处于Query状态,说明这些连接正在执行长时间的SQL,导致无法释放;
  • 如果是Sleep状态,说明连接已归还连接池但还没到idleTimeout被回收,这是正常的,但如果数量超过maximumPoolSize则异常。

希望这些步骤能帮你定位并解决问题!

内容的提问来源于stack exchange,提问作者user9695387

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:56:51