Bernhard Trummer created AMQ-5601:
-------------------------------------

             Summary: XA suspend/resume ending in a rollback not working 
properly (quick-fix attached)
                 Key: AMQ-5601
                 URL: https://issues.apache.org/jira/browse/AMQ-5601
             Project: ActiveMQ
          Issue Type: Bug
          Components: JMS client
    Affects Versions: 5.11.0, 5.10.0, 5.8.0
         Environment: Linux (Debian squeeze)
WebLogic Server 10.3.6.0 with a "Foreign Server" JMS module pointing to 
ActiveMQ.
WebLogic and ActiveMQ running locally.
            Reporter: Bernhard Trummer


The setup:
- ActiveMQ with the default configuration providing one queue.
- WebLogic server having
-- a "Foreign Server" JMS module configured pointing to the ActiveMQ's queue
-- a simple EJB3 MDB hooked up to this queue via XAConnectionFactory.

What the MDB does:
It's annotated with @TransactionAttribute(TransactionAttributeType.REQUIRED), 
thus enforcing an XA transaction.
It calls a method from a @Local EJB, which is annotated with 
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW).
Depending on the JMS message content, it calls mdc.setRollbackOnly() to enforce 
a rollback.

What's happening in the OK case:
- you place a message to the ActiveMQ queue.
- the message is picked up by the activemq-client at WebLogic.
- the MDB is called within an XA transaction.
- when the @Local bean is called, this XA transaction is suspended 
(TransactionContext.end() with flags == TMSUSPEND).
- when the @Local bean returns, the transaction is continued again 
(TransactionContext.begin() with flags == TMRESUME).
- finally, end() with flags == TMSUCCESS and commit() is called.

What's happening in the Rollback case:
- the same until the transaction is resumed
- end() with flags == TMFAIL and rollback() is called.
But, what's going wrong is:
- TransactionContext.beforeEnd() is already called during the end() / TMSUSPEND 
call, which in my opinion does "too much" communication with the broker, 
because a suspend doesn't necessarily mean that the transaction will be ok in 
the end.
- the message stays in the ActiveMQ queue (I have no explanation for that...).
- there's no redelivery of the message to the MDB, as if the message is somehow 
"lost" somewhere within the activemq-client datastructures.
- if WebLogic is shut down, then the message is really "lost" because it also 
vanishes from the ActiveMQ queue.

For our project, I'm going to deploy the attached quick fix, where I just will 
"ignore" the TMSUSPEND / TMRESUME calls to the begin() and end() methods in 
TransactionContext.
So the beforeEnd() method is not called during suspend and in the end every 
"ok" and "rollback" scenarios I tested worked perfectly for me.

I would understand if you don't take over this patch to the ActiveMQ code base, 
because it's in fact "ignoring" XA suspend/resume calls completely instead of 
implementing them properly.
However, I created this issue anyway, because the patch might be of interest 
for other people. Of course without any guarantees that this "works for me" 
patch also "works for you". :-)

BTW:
Is a proper implementation of XA suspend/resume on any roadmap?

Thanks.




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to