Spring 使用 SseEmitter 启动时数据库连接泄漏

Database connection leak in Spring Boot with SseEmitter

我在 Spring Boot 2 中的数据库连接池有问题,即使连接整齐地包装在 @Transactional.

中,连接也不会返回到池中

打开主页后,我运行一个查询,然后打开一个SSE流:

@GetMapping("")
public SseEmitter home() {
  derpService.derp();
  return obs.subscribeSse();
}

derp() 调用如下所示:

@Transactional
void derp() {
    derpRepository.derp();
}

这导致:

@Query(value = "SELECT 'derp'", nativeQuery = true)
void derp();

只要 SSE 流处于打开状态,就不会释放来自 derp() 调用的连接。这可以通过在六个选项卡中打开 http://localhost:8088 轻松显示:第六个选项卡将不会加载,因为所有连接都在使用中。

我在 https://github.com/Oduig/connectionleak 上做了一个最小的例子。 这是 Spring 中的错误,还是我以错误的方式使用 SseEmitter/@Transactional

查看@Andy Wilkinson 的评论:

默认情况下关闭实体是解决方案。 https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-jpa-in-web-environment

我 运行 在我们将 SSE 流引入我们已有 6 年历史的 sprig 引导应用程序时遇到了同样的问题。当我禁用在视图中打开时,我们的应用程序开始抛出错误,因为延迟加载的集合由于缺少会话而未加载。我们将开始清理这些错误,但为了让事情立即生效,我在 application.properties:

中设置了以下属性
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

我希望这会帮助遇到同样问题的人尝试让 SSE 与您的 spring 引导控制器的其余部分一起工作。