hibernate-reactive: Race condition in ProxyConnection
org.hibernate.reactive.pool.impl.ProxyConnection#withConnection often triggers IllegalStateException( "session is currently connecting to database" ) in an application using Quarkus/Mutiny.
Code snippet that triggers the exception:
class Foo {
@Inject
Mutiny.Session mutinySession;
@Path("some-endpoint")
@GET
Uni<String> someEndpoint() {
Uni<String> work = mutinySession.find(SomeEntity.class, someId)
.flatMap(x -> x.toString());
return mutinySession.withTransaction(tx -> work);
}
}
The pseudo-code above is simplified a lot but shall illustrate the problem. We can neglect concurrency aspects here, because the problem is that both the Mutiny.Session.find() and the Mutiny.session.withTransaction() trigger org.hibernate.reactive.pool.impl.ProxyConnection#withConnection.
In many cases, the first call to withConnection() might trigger the creation of a new connection (sets connected=true) and the second call to withTransaction() hits the connected == true && connection == null case resulting in the IllegalStateException.
The problem is related to the state management in withConnection():
- The first invocation sets
connected=trueand triggerssqlClientPool.getConnection(), which is likely async and can run for some time. - Any other invocation (same thread or any other thread) of
withConnection()that arrives before thegetConnection-stage completed will seeconnected==true && connection==nulland trigger theIllegalStateException
Another issue is that the fields used to track the state (closed, connection are not declared volatile/guarded by appropriate fences).
I’ll come up with a patch in a few minutes.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 21 (17 by maintainers)
Commits related to this issue
- [#475] Fix race condition in ProxyConnection.withConnection() In many cases, the first call to `withConnection()` might trigger the creation of a new connection (sets `connected=true`) and the second... — committed to snazy/hibernate-reactive by snazy 4 years ago
- [#475] Fix race condition in ProxyConnection.withConnection() In many cases, the first call to `withConnection()` might trigger the creation of a new connection (sets `connected=true`) and the second... — committed to snazy/hibernate-reactive by snazy 4 years ago
- [#475] Fix race condition in ProxyConnection.withConnection() In many cases, the first call to `withConnection()` might trigger the creation of a new connection (sets `connected=true`) and the second... — committed to snazy/hibernate-reactive by snazy 4 years ago
Yes, the thing about the thread pool is kinda separate from the thing about tracking vert.x context association.
I’m going to open a couple of smaller issues.