I think we would need the same concurrency protection yes. If not today, in the 
near future. 


> On 10 mars 2015, at 15:53, Scott Marlow <smar...@redhat.com> wrote:
> 
> 
> 
>> On 03/10/2015 10:12 AM, Emmanuel Bernard wrote:
>> So Gunnar, your workaround is fine today but will pose problems in the 
>> future if we decide that onRollback for ErrorHandler needs access to the 
>> session somehow to be able to compensate and undo the already executed 
>> operations:
>> - a closed session will do us no good
>> - there is a harder problem that Scott mentions below related to tx reaping 
>> in a different thread
>> 
>> Let’s try and find a solution for the first problem.
>> 
>> @Scott, I think what happens is the following:
>> 
>> - Hibernate registers a Sync when the EM is created (for the flush() 
>> callbacks and a few other things)
>> - Synchronization attached to the Hibernate Transaction objects are 
>> piggybacking on that initial Sync attachement
>> - Wildfly attach a “close session” Sync once it has the instance of 
>> EntityManager
>> - according to your rules, the close session afterTransaction Sync is called 
>> before the one Hibernate put
>> - that explains why Gunnar finds an already closed Tx.
>> 
>> But since Gunnar attaches its Sync when the Hibernate TransactionCoordinator 
>> creates the Hibernate transaction, which is when the EM is created, I can’t 
>> explain why the workaround works.
> 
> Because Gunnar initially registered the Sync, via [3] 
> javax.transaction.Transaction.registerSynchronization(Sync), which might be 
> correct in some non-WildFly environments where perhaps all Syncs are 
> registered via [3] (as non-interposed syncs).  When Gunnar, switched to the 
> Hibernate JtaPlatform mechanism for registering the Sync, we then switched to 
> an interposed Sync.  I suspect that the JtaPlatform sync registration is a 
> good way to register the OGM, however, I have been told that the *best* way 
> is to register only one sync (to avoid ordering issues).
> 
> If OGM could register to share the existing Hibernate EM sync, we would have 
> more control over when the OGM sync is invoked and in which thread 
> (application versus background tm reaping thread).
> 
> Regarding the proposed "new proposal for tx timeout handling using 
> transaction DISASSOCIATING event notification" discussion and how that could 
> impact OGM.  We will continue to run the interposed/non-interposed sync 
> callbacks in whatever thread the TM, calls them from (e.g. beforeCompletion 
> may or may not be called from app thread, afterCompletion will be called from 
> either app thread, background reaping thread or background communications 
> thread).  The reason is that certain resources need to be cleaned up 
> immediately from the Sync.afterCompletion(int status) call.  Certain other 
> resources (like clearing managed entities from persistence context after a 
> rollback), need to be handled from either the application thread or a 
> background thread after the application thread is disassociated from the JTA 
> transaction.
> 
> IMO, the OGM ErrorHandling/Compensation API probably needs to be aware of the 
> same concurrency requirements to avoid presenting the executed operations 
> list, while the application thread is still executing new operations (because 
> it perhaps doesn't yet know that the tx rolled back).
> 
> It would be good to know if OGM will also need the concurrency protection, so 
> that any new Hibernate 5.0 SPI can be used by OGM (e.g. currently the only 
> need is to run the Hibernate Session.clear when we know that the application 
> thread is not actively using the Session).
> 
>> 
>> Emmanuel
>> 
>>> On 10 Mar 2015, at 14:39, Scott Marlow <smar...@redhat.com> wrote:
>>> 
>>> 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#registerInterposedSynchronization%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

Reply via email to