For the sake of posterity (by which I mean my awful memory)... We discussed this on IRC and really we have 2 discussions here, both related to how the Hibernate Transaction API treats registered syncs: 1) The choice of whether to ignore/rethrow exceptions from the syncs 2) The problem with envers specifically not writing audit data in jta environments
(2) was the more troubling to me and we discovered that this only happens with HEM + envers in JTA environments. The issue is that of sync ordering. Essentially what happens is that Hibernate registers a sync named CacheSynchronization. HEM then registers its own sync. The HEM sync takes responsibility to initiate the "managed flush" during beforeCompeletion() callbacks; CacheSynchronization is left to drive the rest of the "before completion" processing within Hibernate. The problem is that since CacheSynchronization was registered first most transaction managers call it first (and even if they do not explicitly, the behavior is non-deterministic; more about that later). In the envers case, that really boils down to its "phase" being executed before the flush which would cause the changes it listens to in order to write its audit records. Obviously we need to better control the ordering there. Then a discussion with the JBossTS team when JBossAS first made the switch for its TM came back to me, namely that JTA/JTS make no guarantees about the order in which registered synchronizations get called. Hibernate's Transaction API (org.hibernate.Transaction) allows registrations of syncs. In JTA environments it currently simply delegates that registration to the underlying JTA transaction. However, this non-ordering issue is concerning. I suggest we alter that behavior to act exactly as well do for JDBC-based transactions, and just host those syncs within our Transaction locally. As for (1), to be honest I still have not seen a compelling argument as to why this should change. Outside of JCA and XA, the danger of mixed heuristics is just too problematic. We discussed various potential ways to allow syncs to signal that they should have their exceptions rethrown should we decide to go that route. On Tue, 2010-07-13 at 15:49 +0100, Emmanuel Bernard wrote: > On 10 juil. 2010, at 09:05, Adam Warski wrote: > > > This, however, as it turns out, causes big problems in a JTA environment > > (with resource-local txs all works fine): audit records are sometimes not > > written. This is because the before tx completion process is called before > > tx synchronizations, and in JTA the auto-flush at the end of a session is > > done using a TX synchronization (AbstractEntityManagerImpl:1020). And it > > doesn't look like exceptions are eaten when thrown from a synchronization > > in JTA - otherwise any exception that occurred during a flush would go > > unnoticed (and I know from practice this doesn't happen ;) ). > > FYI, HEM does register the flush as a Synchronization operation because flush > is conditionally executed (based on the fact that a PC has joined the tx or > not). > I could try and do the beforeCommit phase as an > actionQueue#registerProcess(), but the question is will it fix the problem > all the time? Today the impl seems to rely on a List so it's likely to work > if the em#joinTransaction call is done before Hibernate Search and Hibernate > Envers registrations. > > Emmanuel > > > > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev -- Steve Ebersole <st...@hibernate.org> http://hibernate.org _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev