You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:26:31