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/...
, 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(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/keycloak-user
_______________________________________________
keycloak-user mailing list
keycloak-user(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user