Not exactly sure but this might be the way that Jipijapa registers the JtaPlatform. Originally, Jipijapa used the service approach but reverted that due to a memory leak (I think in envers?).
This was mentioned a while back via [3]. I think we talked about switching Jipijapa back to using a META-INF/services/org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformProvider but I never bothered since the current non-service approach works (except for your use case :). Scott [3] http://lists.jboss.org/pipermail/hibernate-dev/2013-July/010140.html On 03/10/2015 01:14 PM, Gunnar Morling wrote: > For some reason I'm seeing though JBossStandAloneJtaPlatform being used > when debugging an OGM integration test on WildFly. > > WF's JtaPlatform seems not to be picked up. Tried to debug a but, > apparently it never comes to the point where JipiJapa would inject the > JBossAppServerJtaPlatform as platform. I could imagine it's due to OGM > being used as persistence provider, so maybe the right implicit module > dependencies don't get added? Scott? > > It's all a bit guess work on my side, I don't know that WF/JipiJapa code > very well. > > > > 2015-03-10 16:50 GMT+01:00 Steve Ebersole <st...@hibernate.org > <mailto:st...@hibernate.org>>: > > Gunnar, WildFly uses its own JtaPlatform... > > On Tue, Mar 10, 2015 at 10:44 AM, Gunnar Morling > <gun...@hibernate.org <mailto:gun...@hibernate.org>> wrote: > > Hi, > > > I believe that your workaround, mentioned below, of using > JtaPlatform#registerSynchronization() on WildFly, is registering > your > synchronization as interposed via the > TransactionSynchronizationRegistry > [2]. > > That seems not to be the case. If you check out > AbstractJtaPlatform and > TransactionManagerBasedSynchronizationStrategy in ORM, > registerSynchronization() adds the Sync as non-interposed via > TransactionManager.getTransaction().registerSynchronization(). > > But the ordering is indeed what makes me wonder. As > SessionSynchronization > is interposed, the non-interposed beforeCompletion() hooks are > run, but the > non-interposed afterCompletion() hooks managed via > RegisteredSynchronization are never run, as the session has been > closed and > thus the list of syncs to be invoked through > RegisteredSynchronization has > been cleared at this point. At least this behaviour was > surprising to me. > > My work-around works because my non-interposed sync is added through > JtaPlatform to the actual (Arjuna) Transaction instance directly > (rather > than indirectly via RegisteredSynchronization) and thus gets invoked > properly. > > 2015-03-10 14:39 GMT+01:00 Scott Marlow <smar...@redhat.com > <mailto:smar...@redhat.com>>: > > > Hi Gunnar, > > > > Yes, this behaviour is expected since you registered an > non-interposed > > synchronization. For what purpose are you registering the > transaction > > synchronization? I would like to be aware of the > synchronizations that we > > register in WildFly. > > > > The non-interposed sync beforeCompletion callback are invoked > first, then > > the interposed sync beforeCompletion calls, then the interposed > > afterCompletion(int status) calls and finally, the non-interposed > > afterCompletion(int status) calls. > > > > The Synchronizations that are registered via the > javax.transaction. > > > > TransactionSynchronizationRegistry.registerInterposedSynchronization(Synchronization) > > [2] are interposed. > > > > Synchronizations that are registered via the > javax.transaction.Transaction. > > registerSynchronization(Synchronization) [3] are non-interposed. > > > > In WildFly, the transaction manager uses the registration > order within the > > interposed/non-interposed group. Before completion syncs > (within their > > respective group), are run in registration order. After > completion syncs > > (within their respective group), are run in reverse > registration order. > > > > I believe that your workaround, mentioned below, of using > JtaPlatform#registerSynchronization() > > on WildFly, is registering your synchronization as interposed > via the > > TransactionSynchronizationRegistry [2]. There might be a way > to register > > a sync callback at the Hibernate session level (which would > also run as > > interposed sync on WildFly). > > > > Not sure if you saw my email yesterday to Hibernate-dev ml. > You should be > > aware that the afterCompletion(int status) callback, may be > called from a > > non-application thread when the WildFly tm reaper handles tx > timeout (this > > can happen while the application thread is still invoking > calls on the > > Hibernate session). Because the Hibernate session is not > thread safe, we > > need to ensure that the Hibernate session afterCompletion(int > status) > > callback does not mutate the Hibernate session (e.g. calling > > session.clear() what status == rolled back). > > > > Scott > > > > [2] http://docs.oracle.com/javaee/5/api/javax/transaction/ > > > TransactionSynchronizationRegistry.html#registerInterposedSynchronizat > > ion%28javax.transaction.Synchronization%29 > > > > [3] http://docs.oracle.com/javaee/5/api/javax/transaction/ > > Transaction.html#registerSynchronization%28javax.transaction. > > Synchronization%29 > > > > > > On 03/10/2015 09:03 AM, Gunnar Morling wrote: > > > >> Hi, > >> > >> I'm trying to perform a specific action upon transaction > rollback. > >> > >> Assuming this could be done using a custom > >> javax.transaction.Synchronization, I tried to register a > synchronization > >> as > >> follows: > >> > >> TransactionImplementor transaction = ...; // e.g. a > CMTTransaction > >> transaction.registerSynchronization( new MySync() ); > >> > >> And indeed beforeCompletion() is invoked as expected. But > >> afterCompletion() > >> never is. I debugged this a bit on WildFly and observed the > following: > >> > >> * Hibernate ORM registers RegisteredSynchronization with JTA. > >> RegisteredSynchronization manages (indirectly, through > >> TransactionCoordinator, SynchronizationRegistry etc.) those > >> synchronizations added through o.h.t.Transaction. > >> registerSynchronization() > >> * WildFly (specifically, TransactionUtil [1]) registers its own > >> SessionSynchronization > >> for closing the entity manager/session > >> > >> Now that second synchronization is called first, closing the > session. Upon > >> SessionImpl#close(), the SynchronizationRegistry is cleared. > Then when > >> afterComplection() is called on RegisteredSynchronization > afterwards, any > >> previously registered delegate synchronizations are gone > already and thus > >> do not get invoked. > >> > >> I believe I found a workaround for my case by registering my > >> synchronization through > JtaPlatform#registerSynchronization() (which > >> registers it with the actual JTA transaction). > >> > >> My questions are: > >> > >> * Is this behaviour expected? > >> * Is the work-around of doing the registration via > JtaPlatform viable or > >> are there any drawbacks which I'm not aware of? > >> > >> Thanks, > >> > >> --Gunnar > >> > >> [1] > >> https://github.com/wildfly/wildfly/blob/master/jpa/src/ > >> main/java/org/jboss/as/jpa/transaction/TransactionUtil.java > >> _______________________________________________ > >> hibernate-dev mailing list > >> hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org> > >> https://lists.jboss.org/mailman/listinfo/hibernate-dev > >> > >> > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org <mailto:hibernate-dev@lists.jboss.org> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > > > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev