Uploaded image for project: 'ActiveMQ Classic'
  1. ActiveMQ Classic
  2. AMQ-5601

XA suspend/resume ending in a rollback not working properly (quick-fix attached)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Abandoned
    • 5.8.0, 5.10.0, 5.11.0
    • None
    • JMS client
    • None
    • Linux (Debian squeeze)
      WebLogic Server 10.3.6.0 with a "Foreign Server" JMS module pointing to ActiveMQ.
      WebLogic and ActiveMQ running locally.

    • Patch Available

    Description

      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.

      Attachments

        1. xa-suspend-resume-quick-fix.diff
          1 kB
          Bernhard Trummer

        Activity

          People

            Unassigned Unassigned
            slash Bernhard Trummer
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: