Spring Boot并发场景下无法获取JDBC Connection问题求助
解决方案
从你的Hikari日志Timeout failure stats (total=20, active=20, idle=0, waiting=179)可以明确:连接池的所有连接已被完全占用,大量请求在排队等待连接,最终超时失败。以下是针对性的排查和解决步骤:
1. 排查连接泄漏
你已经开启了leakDetectionThreshold=60000,但60秒的阈值可能过高,无法及时捕获短时间的连接泄漏。建议调低阈值,快速定位未释放连接的代码:
spring.datasource.hikari.leakDetectionThreshold=10000
重启应用后,若存在连接泄漏,Hikari会在日志中打印连接占用的堆栈信息,根据堆栈找到未正确关闭连接/事务的代码位置(比如未提交的事务、手动获取连接后未关闭等)。
2. 检查事务管理有效性
- 确认
@Transactional注解是否生效:注解不能用于private方法,若使用了AOP代理,需确保方法被外部调用(内部调用会绕过代理)。 - 检查异常处理逻辑:若事务方法中捕获了异常但未手动回滚,会导致事务一直处于活跃状态,连接无法释放。确保异常被正确抛出或通过
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()标记回滚。 - 避免长事务:若业务中存在耗时较长的操作(比如远程调用、文件IO),不要放在事务范围内,否则会长时间占用数据库连接。
3. 调整连接池参数适配高并发
- 临时增大连接池上限:先确认数据库端的
max_connections限制(比如MySQL执行show variables like 'max_connections';),若数据库允许,将maximumPoolSize调至30-50(需预留部分连接给其他业务):
spring.datasource.hikari.maximumPoolSize=30
- 取消连接池动态扩容:高并发场景下,Hikari动态创建连接的速度可能跟不上请求,将
minimumIdle设为与maximumPoolSize一致,保持连接池始终满负载:
spring.datasource.hikari.minimumIdle=30
- 缩短连接超时时间:当前
connectionTimeout=50000(50秒),过长的等待时间会导致请求堆积,可调至10秒以内,让失败请求快速返回:
spring.datasource.hikari.connectionTimeout=10000
4. 检查数据库端连接限制
若数据库的max_connections过小,即使调大Hikari的连接池也无济于事。以MySQL为例:
- 执行
show variables like 'max_connections';查看当前上限 - 若值较低(比如默认151),修改
my.cnf(或my.ini)中的max_connections参数,重启数据库生效(注意:每个数据库连接会占用内存,需根据服务器配置调整,避免内存溢出)
5. 优化业务SQL与逻辑
- 排查慢查询:开启数据库慢查询日志,找出耗时超过1秒的SQL,优化索引或改写SQL(比如避免全表扫描、拆分复杂查询)
- 批量操作优化:若存在批量保存数据的场景,使用JPA的
batch_insert(需配置spring.jpa.properties.hibernate.jdbc.batch_size),减少连接占用时间
内容的提问来源于stack exchange,提问作者Sard
相关产品推荐
相关产品推荐

