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
相关产品推荐
相关产品推荐

