|This topic relates to Mule ESB Version 2.x.|
To see the corresponding topic in Mule ESB Version 3.x, click [Transaction Management].
Mule's transaction framework is agnostic to the underlying transaction manager. The transaction could be a JDBC transaction, XA transaction, or a JMS transaction or message acknowledgment. All transaction types can be handled the same way. Mule transactions are configured on synchronous endpoints, where an endpoint can be configured to start a new transaction or join an existing one. Transactions are configured on an endpoint using <transaction>, which maps to the org.mule.transaction.MuleTransactionConfig class. This element defines what action an endpoint should take when it receives an event and the transaction factory to use to create transactions.
|If you have multiple inbound or outbound endpoints in a service and you specify a transaction for one of them, you must specify transactions for all of them. For example, if you have two outbound endpoints and you specify a transaction for the first one, you must also specify a transaction for the second one.|
For an excellent article on distributed transactions using both XA and non-XA approaches, see http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html. The multi-resource transaction support described below maps to the Best Efforts 1PC pattern described in the article.
For more details on the elements you configure for transactions, see Transactions Configuration Reference.
For information on using exception strategies to determine whether a transaction gets committed or rolled back in case of an error, see Error Handling with Transactions.
Single-resource transactions (also called "local transactions") are transactions that are provided by the underlying resource, such as JDBC transactions and JMS transactions. These kind of transactions can be used to receive and/or send messages using a single resource only.
An example configuration for a single-resource transaction might look like this:
This configuration defines a global JMS endpoint that receives on a "test.In" queue and another global JMS endpoint that sends on a "test.Out" queue. The action attribute tells Mule what to do for each message. In this case, a new transaction will be created for every message received. The outbound endpoint will use the resource enlisted in the current transaction, if one is running. In this case, it will use the same JMS session that has been used to receive the event. When the message has been routed from the inbound endpoint to the outbound endpoint, the transaction will be committed or rolled back.
You can send multiple messages using the recipient list router, which will send all messages in the same transaction.
You can set action values on the <transaction> element as follows:
- NONE - Never participate in a transaction.
- ALWAYS_BEGIN - Always start a new transaction when receiving a message. If a previous transaction exists, it commits that transaction.
- BEGIN_OR_JOIN - If a transaction is already in progress when an event is received, join the transaction, otherwise start a new transaction.
- ALWAYS_JOIN - Always expects a transaction to be in progress when an event is received. If there is no transaction, an exception is thrown.
- JOIN_IF_POSSIBLE - Will join the current transaction if one is available. Otherwise, no transaction is created.
As of version 2.2, if you are using Mule Enterprise Edition, you can use the <multi-transaction> element to enable a series of operations from multiple JMS resources to be grouped into a single virtual transaction. Multi-resource transactions work without the overhead of XA. The trade-off is that XA reliability guarantees aren't provided, and your services must be ready to handle duplicates. This is very similar to a 1.5 phase commit concept (for a discussion of different approaches, see the JavaWorld article on distributed transactions).
Multi-resource transactions are useful for creating transactional non-XA bridges. For example, if you want to bridge two different JMS connectors, each of which is running local transactions instead of XA transactions, you could configure the multi-resource transaction as follows:
In this example, the local JMS transaction is started when the message is received on the "in" endpoint, and the local WMQ transaction is started when the message is sent out on the "out" endpoint. The last transaction (WMQ) is committed first, and then the previous transaction (JMS) is committed.
Note that when the inbound endpoint has a multi-resource transaction configured on it, any outbound endpoints must also be configured with multi-resource transaction support and the action set to "ALWAYS_JOIN" to become part of the virtual transaction.
You can use XA transactions if you want to enlist multiple managed resources within the same transaction and require 100% reliability. The inbound endpoints are configured in the same manner as for single-resource transactions, but the connectors need to be configured to use XA-enabled resources.
If you run Mule outside an application server, you can use JBoss Transaction Manager to configure an embedded transaction manager.
Currently, only the following transports support XA transactions:
The following example of an XA transaction configuration uses a single transaction to read from a JMS queue and write to a database.
Because the inbound JMS endpoint has an XA transaction configured on it, any outbound endpoints must also be configured with XA transaction support to become part of the XA transaction. This requires that the transport type supports XA transactions. For this configuration to work, you will need to configure a JMS connector that uses a JMS XA Connection Factory and a JDBC connector that is configured to use an XA data source.
Note that although Java EE does not support nested transactions, XA transactions have a suspend/resume concept. Therefore, if a service is configured with an XA transaction set to ALWAYS_BEGIN, and the message is forwarded to another service with an XA transaction set to ALWAYS_BEGIN, the first transaction is suspended until the second transaction completes.
The xa-transaction element is a child element of the abstract-transaction element. It inherits the action attribute from abstract-transaction and the action settings have the same meaning for xa-transaction as they do for abstract-transaction. However, xa-transaction does not inherit the timeout attribute, except as noted in the section below on setting polling frequency.
The xa-transaction element includes another attribute, interactWithExternal, which is a boolean type. When set to true, interactWithExternal causes Mule ESB to interact with transactions begun outside of Mule ESB. For instance, if an external transaction is active and interactWithExternal is set to true, then the BEGIN_OR_JOIN setting for action results in Mule ESB joining the existing transaction while the ALWAYS_BEGIN action attribute setting causes an exception to be thrown. Note that the default value for the interactWithExternal attribute is false.
When you configure an inbound JMS endpoint with XA transactions, the receiver polls every 100 ms. You can change the polling frequency by setting the pollingFrequency property as follows:
This property is only applicable if you are using the XaTransactedJmsMessageReceiver , which is the default receiver on inbound JMS endpoints that use XA transactions. If you are using JBoss transactions, please read here for information on how to configure the timeout value.
Mule uses javax.transaction.TransactionManager for managing transaction spanning multiple resources (XA). If you need the SUSPEND semantics for your transactions (which is what EJB's RequiresNew transaction attribute value does), you must use the transaction manager. Conversely, the more typical javax.transaction.UserTransaction is just a thin handle to a transaction manager with limited (though in most cases sufficient) functionality that does not let you suspend the current transaction.
Note: Depending on your application server vendor, the transaction manager might be available via JNDI or only through proprietary APIs.
The following table summarizes some common Java EE servers:
|Application Server||Remote||Embedded||Common Location||Lookup class|
|WebSphere||Proprietary API call||org.mule.transaction.lookup.WebsphereTransactionManagerLookupFactory|
|Other||Specified via a jndiName property||org.mule.transaction.lookup.GenericTransactionManagerLookupFactory|
For example, to use Weblogic's transaction manager, you would configure Mule as follows:
Transaction demarcation is set on endpoints. The actual management of transactions is handled by the Mule Transaction Coordinator . Note that any transacted event flows will be synchronous. The Transaction Coordinator is a singleton manager that looks after all the transactions for a Mule instance and provides methods for binding and unbinding transaction and retrieving the current transaction state.
For example, to determine whether a transaction is an XA transaction, you could use TransactionCoordination.getInstance().getTransaction().isXa().