beforeCompletion, I need to figure this out

This post is part 6 in a 9-part series on Envers, Spring, and JTA. The next post is An answer, and the previous post is The versioning isn’t happening, part 4a: phone a friend.


I’m just getting back to the envers-JTA-hooks-not-getting-called thing — the following is from work I did last Wednesday —


A post to the Spring Data Access forum had this interesting line:

DEBUG [org.springframework.transaction.jta.JtaTransactionManager] Triggering beforeCompletion synchronization

Hey!  Just when I was beginning to worry that Spring’s JtaTransactionManager had never heard of beforeCompletion and didn’t intend to call that callback.  So… where is that line of code, and who calls it?

Where It Is, and Who Calls It

Back at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(TransactionStatus), this calls its own internal processCommit() method, which — why did we not notice this before? — does these things (among others):


prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);

TriggerBeforeCompletion() ?!  Firing up the ol’ debugger, I do make it in there.  So it *is* trying to run the beforeCompletion Synchronizations, methinks.  Perhaps they aren’t being registered?

triggerBeforeCompletion() calls TransactionSynchronizationUtils.triggerBeforeCompletion(), which calls org.springframework.transaction.support.TransactionSynchronizationManager.getSynchronizations().  (The TransactionSynchronizationManager is also the class that has a registerSynchronization(TransactionSynchronization) method — but instead of taking a javax.transaction.Synchronization, it takes a org.springframework.transaction.support.TransactionSynchronization.)

The only TransactionSynchronization that’s in there currently is a org.springframework.orm.hibernate3.SpringSessionSynchronization.

Envers’ org.jboss.envers.synchronization.VersionsSyncManager.get(EventSource session) calls session.getTransaction().registerSynchronization().  The getTransaction() call returns an org.hibernate.transaction.JDBCTransaction.

Next step: Can we get at that JDBCTransaction from JtaTransactionManager’s doCommit()?  Or alternatively, can the thing passed as an EventSource to VersionsSyncManager.get() be something that wraps a JDBCTransaction and also registers with the Spring TransactionSynchronizationManager?

Advertisements

, ,

  1. Sagas | Our Craft

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s