[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