I've spent quite some time trying to figure out why ActiveMQ retry does
not work for us with JTA, and I may finally have found the reason.
In org.apache.activemq.ActiveMQMessageConsumer.registerSync() there is a
synchronization registered, that would handle the rollback (specifically
deliveredMessages.clear()) so that message is not considered to be
delivered, but can be redelivered.
However, in out case the JTA transaction of the ActiveMQ consumer is
suspended and later resumed, before it is rolled back.
JTA specification
(http://download.oracle.com/otndocs/jcp/jta-1.1-spec-oth-JSpec/?submit=Download)
section 3.2.3:
"When the application’s transaction context is resumed, the application
server ensures that the resource in use by the application is again
enlisted with the transaction. Enlisting a resource as a result of
resuming a transaction triggers the Transaction Manager to inform the
resource manager to re-associate the resource object with the resumed
transaction (XAResource.start(TMRESUME))."
So when JTA transaction is resume()d the Resin JTA transaction manager
calls org.apache.activemq.TransactionContext.start(), in which the the
synchronizations list is set to null!
It seems to me that some JTA implementations do not call
XAResource.start() on resume() even though the spec says so (the way I
read it), which may explain why this works for some people.
Would anyone agree if I claim there is a bug in ActiveMQ, that prevents
it from working properly with resumed JTA transactions...?
</Mattias>
- Synchronizations removed at JTA resume - bug? Mattias Jiderhamn
-