[hibernate-dev] JTA synchronizations on WildFly

Scott Marlow smarlow at redhat.com
Tue Mar 10 14:17:58 EDT 2015


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


More information about the hibernate-dev mailing list