Bug in transactional delivery in an MDB
timfox Jan 7, 2007 10:20 AMI have been looking at http://jira.jboss.com/jira/browse/JBMESSAGING-721 and have uncovered a bug in transactional message delivery with MDBs.
A message is received transactionally in the onMessage method of a MDB and the tx is marked rollback only, but the message is not redelivered.
What is happening is this:
1. JBoss Messaging receives message from destination (no tx at this point)
2. JBM calls onMessage on the MDB container
3. MDB container starts a global tx and enlists the session's xaresoource
4. The user's onMessage executes
5. The user set's rollback only
6. The MDB container rolls back the transaction
7. There is no redelivery since the message was received by JBM *before* the mdb container starts the transaction.
This is a very well known issue and a result of a design flaw in the original JMS connection consumer design.
It is well documented in Weston's favourite book ;), Mark Little's "Java Transaction processing, Chapter 5, section "applications server integration".
Different app servers solve the problem in different ways.
JBoss MQ, JBoss Messaging work by acting as a local transacted session when not in xa begin..end boundaries and then when XAResource.start is called, the work done in the local tx is converted into the work done in the new transaction (See MessagingXAResource.start)
I have fixed this and added tests, however the above behaviour is incompatible with fixes Ovidiu did for:
http://jira.jboss.com/jira/browse/JBMESSAGING-410
(
// leave the session in a 'clean' state, the currentTxId will be set when the XAResource will
// be enrolled with a new transaction.
setCurrentTransactionId(null);
)
Branch_1_0 revision 1317 (19/09/06) by Ovidiu which basically sets the current transaction id to null after a commit or rollback
This breaks the MDB transactional delivery since because the current transaction id is set to null, there is nothing to convert.
The problem here is that the desired behaviour for http://jira.jboss.com/jira/browse/JBMESSAGING-410 and for correct transactional delivery in MDBs seem to be fundamentally incompatible.
For JBMessaging-410 - it wants an XASession to behave as non transacted when it is not enlisted in a global tx - but for correct MDB message delivery we want it to behave as a local session.
My question is, is the requirement for JBMessaging-410 real?
Weston - what should the correct JCA behaviour be here? Is JBMessaging-410 real or bogus and any ideas on how we can reconcile the two?