[hibernate-dev] JTA synchronizations on WildFly
Steve Ebersole
steve at hibernate.org
Tue Mar 10 11:50:11 EDT 2015
Gunnar, WildFly uses its own JtaPlatform...
On Tue, Mar 10, 2015 at 10:44 AM, Gunnar Morling <gunnar at 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 <smarlow at 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 at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> >>
> >>
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
More information about the hibernate-dev
mailing list