Don't know where to post it actually, here, in messaging or infinispan.. the problem affects all of them.
Suppose we have a EJB application with it's own persistence mechanism, which uses a transactional cache to speed up DB reads.
It implements some process that involves background data processing. We would like it to work like this:
Transaction T1 creates/modifies some data in DB, makes corresponding changes in cache and sends a JMS message
MDB receives this message, starts transaction T2 and wants to process the same data T1 was touching.
Since we're using transaction we want T2 to start after T1 completes, so we won't get stale data in DB/cache due to isolation. In case of JBoss it means using "java:/JmsXA" connection factory, which ends up registering an XAResource and sending JMS message from the commit() call. So far so good.
But in reality we're still getting a race condition on commit. Both JBossCache and, last I checked, Infinispan as well, use Synchronization.afterCommit() for tx. synchronization and committing it's data. It obviously gets called by the TM after calling commit() on all the XAResource's, and sometimes it arrives 100-200ms later for me. So sometimes JMS message hits MDB and gets processed before cache commits, and thus it can get stale data from it.
I must be honest here, I'm not using JBossCache/Infinispan but some home-made transactional cache that uses afterCompletion as well, but as far as I can see form the sources - JBoss code does the same.
OK, as a workaround I've switched from Synchronization.afterCompletion to Transaction.enlistResource(my XAResource) and now I'm committing cache changes from commit() - at the right time.. or not?
Say, if we have several XA resources enlisted, JMS thing being one of them, we still can't guarantee any ordering. If JMS's commit is called first, sends a message and MDB kicks in, in the meanwhile some heavy resource commits for 5 seconds and only then we get to DB/cache commits we're still screwed.
Please can somebody enlighten me on the matter.