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: transactions.
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”.
Action | interactWithExternal value | Result |
NONE | true | Throw an exception if any transaction is active. |
NONE | false | Throw an exception if a Mule transaction is active. |
ALWAYS_BEGIN | true | If no transaction is active, begin a new one. Otherwise, throw an exception. |
ALWAYS_BEGIN | false | If 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_JOIN | true | If any transaction is active is started, join it. Otherwise, begin a new transaction. |
BEGIN_OR_JOIN | false | If 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_JOIN | true | If any transaction is active, join it. Otherwise, throw an exception. |
ALWAYS_JOIN | false | If a Mule transaction is active, join it. Otherwise, throw an exception. |
JOIN_IF_POSSIBLE | true | If any transaction is active, join it. |
JOIN_IF_POSSIBLE | false | If 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
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