Spring Boot+HikariCP连接池耗尽及事务异常问题求助
问题根源分析与解决方案
兄弟,你这问题一眼就能看到两个核心问题:连接池配置完全搞反了,还有事务管理的细节没做到位,咱们一个个说:
1. HikariCP连接池配置逻辑完全错误,这是连接超时的元凶
你看你配置的参数:
spring.datasource.hikari.minimumIdle=250 spring.datasource.hikari.maximumPoolSize=5
这完全是把参数搞反了啊!minimumIdle是连接池要维护的最小空闲连接数,它的值绝对不能大于maximumPoolSize(连接池允许的最大连接数)。HikariCP会拼命创建连接,试图满足250个空闲连接的要求,但你的最大池只有5,根本做不到,这就导致连接池一直处于“忙死也达不到要求”的状态,新请求过来根本拿不到可用连接,直接超时抛出java.sql.SQLTransientConnectionException。
另外你设置的maxLifetime=500毫秒也离谱,连接刚创建就会被销毁,频繁创建销毁连接只会加重系统负担,完全没必要。
给你一个合理的基础配置参考:
spring.datasource.hikari.minimumIdle=2 spring.datasource.hikari.maximumPoolSize=10 spring.datasource.hikari.idleTimeout=60000 spring.datasource.hikari.poolName=SpringBootJPAHikariCP spring.datasource.hikari.maxLifetime=1800000 spring.datasource.hikari.connectionTimeout=3000
minimumIdle设置成比maximumPoolSize小的值,一般2-5就够,可根据你的并发量调整maxLifetime改成30分钟(1800000毫秒),这是HikariCP推荐的合理值idleTimeout设为1分钟,空闲超过1分钟的连接会被回收
2. TransactionRequiredException是因为getCurrentSession()需要绑定事务
Hibernate的session.getCurrentSession()不是随便能用的,它返回的会话是绑定到当前活跃事务的。如果你的代码里没有开启事务,直接调用这个方法就会报错。
解决方法很简单:
- 在你的Service类的业务方法上加上
@Transactional注解(Spring Boot默认已经启用了事务管理,只要你的Service类被Spring扫描到就行) - 一定要让Controller调用Service层,再由Service层调用DAO层,事务的控制应该放在Service层,而不是直接在Controller或DAO里操作
额外排查建议
如果修正配置和事务后还有问题,你可以检查:
- 有没有连接泄漏:如果你之前用的是
session.openSession(),一定要确保在finally块里关闭Session,或者用try-with-resources语句自动关闭 - 验证PostgreSQL本身的连接:确认数据库服务正常,用户名密码正确,你的应用用户有足够的权限创建连接
内容的提问来源于stack exchange,提问作者theRoot
相关产品推荐
相关产品推荐

