[keycloak-user] ProviderFactory::postInit + transactions = startup failure

Dmitry Telegin mitya at cargosoft.ru
Wed Jun 28 14:18:24 EDT 2017


Hi,

(TL;DR) if a KeycloakTransaction is opened from
ProviderFactory::postInit, sometimes the transaction is already active
on the underlying
org.jboss.jca.adapters.jdbc.local.LocalManagedConnection, which leads
to errors.

(full version) I think it's essential for the providers to be able to
access realm data in postInit(). For that, a transaction is required;
using KeycloakModelUtils.runJobInTransaction() is a convenient method
to do that:

    @Override
    public void postInit(KeycloakSessionFactory factory) {
        KeycloakModelUtils.runJobInTransaction(factory,
(KeycloakSession session) -> {
            List<RealmModel> realms = session.realms().getRealms();
            // do stuff
        });
    }

When such a provider is deployed, in about half of cases Keycloak fails
to start due to the following exception:

java.sql.SQLException: IJ031017: You cannot set autocommit during a
managed transaction

(see full stacktrace here https://pastebin.com/ETtPqXQk)

I've managed to track it down to something that looks like transaction
clash over a single instance of
org.jboss.jca.adapters.jdbc.local.LocalManagedConnection. What happens
is that the two treads at the same time begin two KeycloakTransactions
which end up with the same instance of LocalManagedConnection. The
above exception results from the second begin() call.

There's a system property called "ironjacamar.jdbc.ignoreautocommit"
that allows to ignore the situation, but I think it's dangerous because
it doesn't eliminate the transaction clash, just suppresses the check.
If I'm not mistaken, this began to happen around Keycloak 2.2.x, which
coincides with the changes to Keycloak transaction management. That
said, do I need now some additional transaction coordination with the
rest of Keycloak, or is it a bug? If former, how do I do that? If
latter, how do we fix it?

I hope we'll sort it out, since the ability to access the data at every
phase of provider's lifecycle seems something fundamental to me.

Regards,
Dmitry


More information about the keycloak-user mailing list