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

Spring Boot WebSocket应用出现JDBC连接池耗尽无法获取连接问题求助

问题分析与解决方案

从你的错误信息HikariPool-1 - Connection is not available, request timed out来看,核心问题是数据库连接池被耗尽了,根源出在你的EntityManager和事务管理代码上,结合细节给你拆解一下:

1. 为什么会耗尽连接?

你手动创建了EntityManager但没有正确关闭它:

EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// ... 业务代码
entityManager.getTransaction().commit();
// 这里没有关闭EntityManager!

每次执行这段代码,都会从连接池获取一个连接,但使用后没有释放,日积月累连接池就被占满,新请求拿不到连接就超时了。

另外你还混用了Spring Data JPA的entityRepository.save()和手动的EntityManager事务——Spring Data JPA的Repository方法本身已经由Spring管理事务和连接,手动开事务再调用save,会导致连接资源的重复占用和释放异常。

2. 修复方案

方案一:完全使用Spring Data JPA的自动事务管理(推荐)

删掉手动的EntityManager代码,让Spring帮你管理事务和连接,这是Spring Boot的最佳实践:

// 确保你的Service类上加上@Transactional注解
@Service
@Transactional
public class YourService {
    private final EntityRepository entityRepository;

    // 构造注入
    public YourService(EntityRepository entityRepository) {
        this.entityRepository = entityRepository;
    }

    public void updateEntity(Object object) {
        // 先查询出实体(假设你有id参数)
        Entity entity = entityRepository.findById(object.getString("id"))
                .orElseThrow(() -> new RuntimeException("Entity not found"));
        entity.setName(object.getString("name"));
        // 直接save,Spring会自动处理事务和连接
        entityRepository.save(entity);
    }
}

这样Spring会自动帮你处理连接的获取与释放,不会出现连接泄漏。

方案二:如果必须手动使用EntityManager

一定要用try-with-resources语法确保EntityManager被关闭,或者在finally块里手动关闭:

// try-with-resources会自动关闭EntityManager
try (EntityManager entityManager = entityManagerFactory.createEntityManager()) {
    entityManager.getTransaction().begin();
    entity.setName(object.getString("name"));
    // 这里不要用repository.save,改用EntityManager的merge方法
    entityManager.merge(entity);
    entityManager.flush();
    entityManager.getTransaction().commit();
} catch (Exception e) {
    // 异常时回滚事务
    if (entityManager != null && entityManager.getTransaction().isActive()) {
        entityManager.getTransaction().rollback();
    }
    throw e;
}

方案三:调整连接池配置(辅助优化)

如果你的业务确实需要更多连接,可以在application.properties或application.yml里调整HikariCP的参数:

# 最大连接数,根据数据库配置和业务调整,默认是10
spring.datasource.hikari.maximum-pool-size=20
# 连接超时时间,默认30秒,可适当缩短
spring.datasource.hikari.connection-timeout=10000
# 空闲连接超时时间,自动释放闲置连接
spring.datasource.hikari.idle-timeout=600000

3. 额外注意点

  • 不要混用手动事务和Spring的声明式事务,避免资源管理混乱;
  • Spring Boot的spring-boot-starter-data-jpa已经默认集成了HikariCP,无需额外配置连接池,但可根据业务调整参数;
  • 你的Gradle配置里用了Spring Boot 2.2.0的快照版,建议换成同系列的稳定RELEASE版本,避免潜在的未知bug。

内容的提问来源于stack exchange,提问作者Sixiy2616

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:01