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=true and triggers sqlClientPool.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 the getConnection-stage completed will see connected==true && connection==null and trigger the IllegalStateException

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

Most upvoted comments

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.