Transaction Synchronization and MDBs
pacodelucia Aug 19, 2013 11:07 AMHi
Not sure if this is the right place to ask. It's more a general question regarding transaction handling in a JEE-Container and MessageDrivenBeans.
Let's assume an EJB writes to a database and to a JMS queue. This is done inside a XA-Transaction. An MDB is reading the messages written to the queue and relies on the data written to the database before.
What is clear:
- The transaction the MDB is running in (if there is any) is not related at all to the first XA-Transaction. A transaction context is not passed with a message.
- XA guarantees that the the data is written to the database AND the queue or in case of a failure to neither of them. (ok, there can still occure some heuristic exception and so, but generally this should not happen)
Within the two-phase-commit protocol first the prepare-statement is sent. DB and queue respond with ok (or something like this) and then the Transaction Manager sends the commit command. If everything is fine the resource manager from database and queue send an acknowledge message.
Now to the question: The acknowledge messages may take some time to get from the resource managesr to the transaction manager. And also the commit message may take some time to get from the transaction manager to the resource manager. It might be that the queue commit is done before the database commit. So the question is: When is the onMessage() method called in the MDB? Right after the queue commit is done? Or does the Container wait until the acknowledge messages from both resource managers (db and queue) are received before invoking onMessage()?
So is this behaviour defined somewhere? I observed that the database was always up-to-date when accessing it from the MDB and when I consumed the message from the same queue. However it did not work anymore when I started using a divert that diverted the message to a second queue and the reading from this second queue. Several times I had the problem that the data was not in the database yet. This is either a timing issue or the container in this case does not wait because he doesn't know that the first queue is related to the second queue (because this is on a remote hornet queue server). Of course a solution could be to use a message delay (that's what I did).
So my question is more a theoretical one. I don't really need a solution.
I searched several specifications like EJB, JTA, JTS, etc. for an explanation but could not find anything. Hopefully someone can help here..
Regards
Oliver