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 引导控制器的其余部分一起工作。
我在 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 引导控制器的其余部分一起工作。