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

Marek Posolda mposolda at redhat.com
Mon Jul 3 06:10:41 EDT 2017


Hi,

I think it's not good to directly start transactions from postInit. 
Among the issues you mentioned, various initial steps (eg. migration 
from previous version, export/import) may not be yet finished at this 
stage. Probably you can either:
- Register listener for PostMigrationEvent in your postInit. See the 
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/authentication/PushButtonAuthenticator.java 
for inspiration.
- Use the pattern with "lazyInit" like for example here 
https://github.com/keycloak/keycloak/blob/master/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java#L78 
, which is called 1st time before your provider is actually needed.

Maybe we can improve by provide more callback methods to 
ProviderFactory/Provider to avoid the lazyInit pattern directly in 
providers, but rather integrate it better with the Provider framework. 
But for now, I think that some of the workaround above should work for 
you IMO.

Marek

On 03/07/17 03:50, Dmitry Telegin wrote:
> https://issues.jboss.org/browse/KEYCLOAK-5132
>
> Meanwhile I've found a workaround - just run a transaction in a new
> thread. However, this should be a "managed thread" - see issue details
> & comments for more info.
>
> В Wed, 28/06/2017 в 21:18 +0300, Dmitry Telegin пишет:
>> 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
>> _______________________________________________
>> keycloak-user mailing list
>> keycloak-user at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-user
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user




More information about the keycloak-user mailing list