My understanding, that if transacted session is used, JMS guarantees that any given message delivered only once.
If you consume a message in a tx, *and that tx is committed* then the message is guaranteed to never be delivered again. But in your case the tx is never committed, it is rolled back. Rollback causes redelivery (see JMS spec).
It's the recovery manager (I assume you're using JBoss TS), not JBM that decides to commit or rollback. In this case it decides to rollback. Most probably another transaction branch in the same XA transaction failed to prepare (the database update) so this would be correct behaviour.
I agree with what you said, but it is not what happened. In my scenario there were three delivery attempts.
1) The first one failed and was eventually rolled-back.
2) The second one committed. It happened as soon as JBM client started up after the failure and reconnected to the remote queue (step 4 in my post). And this is a problem since the first transaction was still in progress (not recovered yet!).
3) The last one is a legitimate redelivery (step 6), committed. It happened after recovery of the first transaction (rollback) and queue was restarted.
It looks like the problem is that when the client died after prepare, the queue MBean shows message as available, and delivers it right away even the JBM tables show the message as locked in transaction, waiting for TM to complete the transaction.
I know it is hard to read such a long post, but hope you will find time to comment.
I am running JBoss 4.2.2 + JBM 1.4.0.SP3.
BTW, the same problem (two committed deliveries of the same message), happens if TM recovery commits. I can reproduce both cases.