We have a system that relies heavily on JMS for its functionality, and we are seeing some odd behaviour from JBM.
Here is a brief explanation of our system;
- An event processor periodically scans the database for interested events and notifies appropriate components in the system about the new event
- The relevant component does some processing of the data that is available at that instant and sends back the SUCCESS or FAILURE message to the event processor.
- In case any exception occurred while processing the event in a particular component of the system, that component signals rolling back of the whole transaction, and sends a RETRY (after some preconfigured time) message to the event processor.
- The event processor retries to notify the respective component for a few times (preconfigured) and if the event is still not processed successfully, it finally marks that event as FAILED.
We are seeing strange behaviour with respect to the point number 3 that is mentioned above. While the spec says that rolling back a container managed transaction in MDB's onMessage method ( by invoking mdbContext.setRollbackOnly(true) ) would ensure that the message gets redelivered by the JMS engine, we are observing that no message redelivery is attempted by JBM and instead the additional message that our component sends to the event manager is also successfully devliered (from the rolled back transactional MDB instance).
I have to mention that at the time when the respective component was coded, we did not reallize that we need to span a nested transaction (possibly bean mabaged) if we want to roll back just those changes made with in the component and ensure that the actual JMS message gets successfully processed from teh JBM engine perspective. So, we have relied on the behaviour that sending a new JMS message to back to the event processor works even after rolling back the transaction from onMessage() method of MDB.
Things have been working fine like this for quite some time but occasionally we see that the JMS message being redevliered by JBM at very quick succession and that particular event which had suffered this fate would end up with no state, i.e. neither SUCCESS, nor FAILURE; the RETRY message would not reach the event processor and hence retry was also not attempted-- thus in an indeterminate state.
I have a few questions here:
- Why is JBM behaving different from what is defined in spec, i.e. why is the message not redelivered when the transaction is rolled back?
- Why is the additioanal message being sent from the respective component to the event processor successfully even from within a rolledback transaction?
- Why does the JBM attempt to redelvier the message, on transaction rollback, only occassionally?
- Is the analysis made so far correct?
- If so, can i change my code to spawn a nested (bean managed) transaction within the MDB so that the rolling back of that transaction will not have nay impact on the global transaction?
Please give me some advice and direction...
Thanks and Regards,