Transactions: Joining the outside world

motif

One of the strengths of the Mule ESB is its ability to share many kinds of resources with the rest of the software environment: libraries, Spring beans, transaction managers, and many more.  Starting in Mule 2.2.6 and 3.0, there’s another thing Mule can share: .

In JTA, the Java Enterprise Edition API for transaction processing, transactions are tied to threads.    When Mule is entered from user code it’s possible that a transaction has already been started on the current thread, and Mule might want to join it rather than starting a new (nested) transaction.    You can control this with a new, optional boolean attribute on the <xa-transaction> element called interactWithExternal.  The default value is false, which make Mule act like it did in previous versions.  The way that the two transaction-controlling attributes action and interactWithExternal combine is straightforward if you keep in mind what the two interactWithExternal settings mean:

  • true — pay attention to transactions started outside of Mule
  • false — ignore transactions started outside of Mule

The complete set of rules is below.  For simplicity, we call a transaction started by Mule a “Mule Transaction”, and a transaction started by user code a “non-Mule transaction”.

ActioninteractWithExternal valueResult
NONEtrueThrow an exception if any transaction is active.
NONEfalseThrow an exception if a Mule transaction is active.
ALWAYS_BEGINtrueIf no transaction is active, begin a new one.
Otherwise, throw an exception.
ALWAYS_BEGINfalseIf no Mule transaction is active, begin a new one. If a non-Mule transaction was active, this new transaction will be nested inside it.
Otherwise, begin a new transaction.
BEGIN_OR_JOINtrueIf any transaction is active is started, join it.
Otherwise, begin a new transaction.
BEGIN_OR_JOINfalseIf a Mule transaction is active, join it.
Otherwise, begin a new transaction. If a non-Mule transaction was active, this new transaction will be nested inside it.
ALWAYS_JOINtrueIf any transaction is active, join it.
Otherwise, throw an exception.
ALWAYS_JOINfalseIf a Mule transaction is active, join it.
Otherwise, throw an exception.
JOIN_IF_POSSIBLEtrueIf any transaction is active, join it.
JOIN_IF_POSSIBLEfalseIf a Mule transaction is active, join it.

For example, suppose the processing of a message received at an endpoint should join the current transaction regardless of whether that transaction was started by Mule or by non-Mule code. This can be configured as

If, one the other hand, only mule transactions should be joined, configure

<vm:endpoint name="inbound.mule.endpoint" path="in">
  <xa-transaction action="JOIN_ALWAYS" interactWithExternal="false"
  />
</vm:endpoint>

It would also work to omit interactWithExternal, since its default value is false.

All of this is documented at Transaction Management, along with other information about managing transactions with Mule.  In particular, the entire section on XA Transactions is extremely useful


We'd love to hear your opinion on this post