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>: > Gunnar, WildFly uses its own JtaPlatform... > > On Tue, Mar 10, 2015 at 10:44 AM, Gunnar Morling <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>: >> >> > 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 >> >> 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 >> > > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev