Spring Boot 1.5集成测试连接池泄漏问题求助
解决Spring Boot 1.5 + C3P0 + Azure SQL连接数暴涨崩溃问题
这问题我之前帮好几个开发者排查过,核心是连接泄漏加上C3P0配置没适配Azure SQL的特性,咱们一步步来解决:
一、先给C3P0加上核心限制和健康检查配置
默认的C3P0配置没有严格限制最大连接数,而且Azure SQL会主动回收闲置连接,导致连接池里的失效连接越来越多,应用不断创建新连接直到耗尽资源。直接在application.properties里加这些配置:
# 限制连接池最大连接数,根据测试套件并发量调整,100足够覆盖大部分场景 spring.datasource.c3p0.maxPoolSize=100 spring.datasource.c3p0.minPoolSize=10 # 闲置连接1800秒(30分钟)后自动回收 spring.datasource.c3p0.maxIdleTime=1800 # 每次获取连接时检查有效性,避免拿到Azure已经回收的死连接 spring.datasource.c3p0.testConnectionOnCheckout=true # 适配SQL Server的简单测试SQL spring.datasource.c3p0.preferredTestQuery=SELECT 1 # 每300秒(5分钟)检查一次闲置连接状态 spring.datasource.c3p0.idleConnectionTestPeriod=300 # 连接不足时每次新增5个连接 spring.datasource.c3p0.acquireIncrement=5
二、排查代码里的连接泄漏点
你用@PersistenceContext注入的EntityManager本应由容器自动管理连接,但还是要检查这些场景:
- 有没有手动获取JDBC连接后没正确释放?比如这种场景一定要在finally块里关闭资源:
Connection conn = null; try { conn = entityManager.unwrap(Connection.class); // 执行数据库操作 } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { /* 日志记录异常 */ } } } - 测试用例里的
@Transactional有没有异常未处理?比如未捕获的异常可能导致事务无法回滚,连接一直被占用。
三、优化测试套件的上下文复用
Spring Boot 1.5的@SpringBootTest默认会缓存ApplicationContext,但如果测试类用了不同的@TestConfiguration或@Profile,会创建多个独立上下文,每个上下文都带自己的连接池,连接数自然叠加。解决方法:
- 统一用基础测试类让所有测试共享同一个上下文
- 给测试类加上
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS),确保测试结束后销毁上下文释放连接(注意这会减慢测试速度,按需使用)
四、验证JDBC驱动版本兼容性
mssql-jdbc 6.1.0.jre8和Spring Boot 1.5的兼容性没问题,但这个版本偏旧,可能存在连接管理的小bug。可以尝试升级到6.4.0.jre8(这个版本和Spring Boot 1.5适配更稳定),不用改代码,只替换依赖版本即可。
五、测试验证
改完配置和代码后,重新跑测试套件,同时用netstat监控连接数:
- 正常情况下连接数会稳定在
maxPoolSize以内,不会无限增长 - 如果仍有泄漏,用C3P0的JMX监控工具查看连接池状态,定位未释放连接对应的线程和代码位置
内容的提问来源于stack exchange,提问作者Gerb
相关产品推荐
相关产品推荐

