Search code examples
hibernatespring-bootserver-sent-events

Database connection leak in Spring Boot with SseEmitter


I have a problem with a database connection pool in Spring Boot 2, where connections are not returned to the pool even though they are neatly wrapped in @Transactional.

Upon opening the home page, I run a query and then open an SSE stream:

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

The derp() call looks like this:

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

Which leads to:

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

As long as the SSE stream is open, the connection from the derp() call is not released. This can easily be shown by opening http://localhost:8088 in six tabs: the sixth tab will not load because all connections are in use.

I made a minimal example on https://github.com/Oduig/connectionleak. Is this a bug in Spring, or am I using SseEmitter/@Transactional in the wrong way?


Solution

  • See the comment by @Andy Wilkinson:

    Closing entities by default is the solution. https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-jpa-in-web-environment