I don't know if it is a JMS bug, or we do something wrong.
We have an application that runs like this:
1. Get request from the persistent input queue - transaction begins.
2. Process the request (the MDB that got the request calls some Session Beans here).
3. Place the answer in the persistent output queue.
4. Commit the transaction (actually this is done inside Jboss when the MDB's onMessage() finishes without errors).
Messages from the output queue are sent to the user.
Everything is fine until the request cannot be processed (e.g. a deadlock occurs) and raises a non-recoverable exception. We catch this exception, print it out to the log and mark the transaction to rollback by calling:
currentContext.setRollbackOnly(). JMS notices the rollbacked transaction and tries to redeliver the message from the input queue once again correctly (we have set the redelivery limit >0 for the input queue).
Unfortunately if the server had managed to place the message in the output queue BEFORE the exception was raised, the message is sent to the user anyway!!! This violates ACID! What should we do to make JMS drop the messages that are placed by the rollbacked transaction?
It is not possible to do all the possibly unsafe stuff before sending output to the user. We would have to build our own messaging system for that and we believe there is a better way.
Unfortunaltely this forum doesn't support post removal. I solved the problem.
The answer is acually in FAQ:
Use the "java:/JmsXA" connection factory.
We used the wrong connection factory - there should have been "java:/JmsXA" instead of "ConnectionFactory" (I've no idea, who in our team placed that there - this bug seems to be there for years :D)