Spring Boot多数据源场景下Hikari连接池抛出Connection is closed异常排查
应用正常运行数小时后,开始抛出以下SQL异常:
java.sql.SQLException: Connection is closed
at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.lambda$getClosedConnection$0(ProxyConnection.java:515)
at com.sun.proxy.$Proxy171.prepareStatement(Unknown Source)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2104)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2034)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012)
at org.hibernate.loader.Loader.doQuery(Loader.java:953)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
at org.hibernate.loader.Loader.doList(Loader.java:2838)
at org.hibernate.loader.Loader.doList(Loader.java:2820)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2652)
at org.hibernate.loader.Loader.list(Loader.java:2647)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2131)
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1163)
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:173)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
at org.hibernate.query.Query.getResultList(Query.java:165)
对应的查询调用代码如下:
@Autowired private final EntityManager entityManager; void someMethod() { var q = entityManager.createNativeQuery(query); var rs = q.getResultList(); // 异常抛出位置 // 其他代码 }
最近新增了多数据源配置,怀疑此操作引发了该问题,但无法确认,需要排查思路和解决方案。
排查方向与解决方案
1. 多数据源的EntityManager配置校验
- 确认每个数据源对应的
EntityManagerFactory、EntityManager是否完全隔离,避免跨数据源的连接混用。若多个EntityManager共享连接池或配置错误,会导致连接被提前关闭。 - 检查是否为每个数据源配置了独立的事务管理器,确保事务边界清晰,不会出现一个事务关闭另一数据源连接的情况。
2. Hikari连接池参数调整
- 连接生命周期匹配:检查
maxLifetime、idleTimeout配置,确保这两个值小于数据库端的连接超时时间(如MySQL的wait_timeout)。若连接池的连接存活时间超过数据库设置,数据库会主动关闭连接,而连接池仍认为连接可用,触发异常。 - 开启连接泄漏检测:设置
leakDetectionThreshold(如2000毫秒),若存在连接未被正确释放,会打印泄漏日志,快速定位问题点。 - 合理设置最小空闲连接:调整
minimumIdle值,避免连接池中的连接被频繁销毁重建,导致连接状态不一致。
3. EntityManager生命周期管理
- 确认
EntityManager的注入逻辑:容器管理的EntityManager(@Autowired注入)默认是事务范围的,事务结束后会自动关闭连接。若在非事务方法中使用,或手动干预了EntityManager生命周期,可能导致连接提前关闭。 - 避免长期持有EntityManager实例:不要将EntityManager作为类成员变量长期持有,应在方法内按需获取,或通过
EntityManagerFactory动态创建实例。
4. 事务边界规范
- 检查
someMethod是否添加了@Transactional注解,若未添加,EntityManager使用的是非事务性连接,连接生命周期由Hikari管理,空闲时可能被回收。如需稳定使用连接,需添加事务注解,并在多数据源场景下指定对应的事务管理器(通过value属性)。 - 确保事务注解指定了正确的事务管理器,避免用默认事务管理器操作错误的数据源。
5. 数据库端配置检查
- 查看数据库的连接超时设置(如MySQL的
wait_timeout、interactive_timeout),确保这些值大于Hikari的maxLifetime,防止数据库主动关闭连接池中的连接。
内容的提问来源于stack exchange,提问作者Forece85

