Closed Oduig closed 6 years ago
In the interests of keeping the discussion in one place, the question on Stack Overflow is sufficient.
I experienced the same problem. I could not find anything in the spring and spring boot reference manual that warned against the use of @Transactional
in combination with SSEEmitter
and open entitymanager in view.
Unless I'm mistaken we could fix the issue in OpenEntityManagerInViewInterceptor
and OpenSessionInViewInterceptor
(and probably also the filters) by closing the entitymanager in afterConcurrentHandlingStarted
(as is done in afterCompletion).
I don't see any reason to keep the entitymanager open at the moment: is this a bug or is there a use case for this that I'm unaware of?
@janickr This is closed, I found the solution myself and posted it on SO. Did you try adding spring.jpa.open-in-view=true
to your application config?
@Oduig Hi thanks for the reply!
I know, I read the SO thread before I found this bug ticket. But only after spending more than a day figuring out why my connection pool kept exhausting after a while. IMO this is still a bug (unless I'm missing something about the nature of async web requests and entity managers)
The reason I commented on this ticket is this: it is really not that obvious that @Transactional
in combination with spring.jpa.open-in-view
and SseEmitter
can lead to connection leaks.
If this is expected (and intended) behaviour, it would be desirable that it is documented in the spring reference here : https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async-sse (as such it is a documentation bug)
If not, it is a bug in the framework code, and we should try to fix this. So that is why I wondered why afterConcurrentHandlingStarted
would unbind the entityManager without actually closing it.
@janickr feel free to contribute a PR to the Spring Framework project, or start a discussion with a new issue. I suspect that this will be a hard one to tackle since it's generally applicable to "you should not bind resources to a persistent connection/streaming responses if they're likely to deplete a pool of resources".
@bclozel this issue occurs without "binding resource to a persistent connection".
i'm also experiencing the same issue. i have no idea how to release the connection. as a temporary fix i have removed invoking database queries which creating sseemitter.
If you’re starting a transaction, a streaming query or if the session is configured to stay opened with the view, you are effectively binding that database resource to the persistent connection. If you believe you’ve found a different problem, please create a new issue with a sample, minimal project that reproduces the behavior.
@bclozel thank you, i think its the same problem not different
spring.jpa.open-in-view = false
adding above property fixed the issue. it detaches the dbconnectionSession from the incoming session.
references
spring.jpa.open-in-view = false
is not the answer since majority of spring applications relies on lazy loading of entities and their fields. This means that keeping connection open is a bug when working 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:
The
derp()
call looks like this:Which leads to:
As long as the SSE stream is open, the connection from the
derp()
call is not released. This goes against my intuition, because I assumed@Transactional
would return the connection as soon as the flow exits the transaction scope.Is this a bug in Spring?
Steps to reproduce
docker-compose up -d --build
http://localhost:8088
in six tabsResources