---
schema_version: "1"
id: bdb933ad86222877a90b79c15430115da90d9e6268c8ec7a9b759ff1f57799e4
title: Transaction Management
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-runtime/4.12/transaction-management.md
canonical_url: https://docs.mulesoft.com/mule-runtime/4.12/transaction-management
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 2a6c69c92f5750f96c0fc8bcacedd1048e11cc5beaef4f8959d19c9a2ad40b19
description: MuleSoft Documentation Site
release: "4.12"
latest: false
---
---
product: Mule Runtime
version: 4.12
keywords: transaction, management, demarcation, jms, jdbc, vm, database, resource, xa, tx
---

# Transaction Management

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

Transactions are operations in a Mule app for which the result cannot remain indeterminate. When a
series of steps in a flow must succeed or fail as one unit, Mule uses a transaction to demarcate
that unit.

For example, you might use a transaction to encapsulate several steps in a flow that result in
committing information to a database. In this type of scenario, the commit (or transaction) is
either entirely complete and succeeds, or is incomplete and fails. Even if partially complete, the
commit fails. When a transaction fails, Mule rolls back the operations within the transaction so
that no part results in partial completion.

Implement a [Reliability Pattern](https://docs.mulesoft.com/mule-runtime/4.12/reliability-patterns) to design your application so it is capable
of reliable messaging, even if the application receives messages from a non-transactional connector.

You can also configure Bitronix to manage transactions in your Mule application.

## Transaction Types

Mule supports Single Resource (Local, the default) and Extended Architecture (`XA`) transaction
types (`transactionType`). The only components that can define the transaction type are event
sources (for example, `jms:listener` and `vm:listener`) and the Try scope.

The following table describes the characteristics of each transaction type and the requisites for an
operation to join the transaction:

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Transaction Type</th><th>Characteristics</th><th>Requisites to Join the Transaction</th></tr></thead><tbody><tr><td><div><div><p><a href="https://docs.mulesoft.com/mule-runtime/4.12/single-resource-transaction">Single Resource (Local)</a></p></div></div></td><td><div><div><ul><li><p>Performs better than XA transactions.</p></li><li><p>Does not support nested transactions.</p></li></ul></div></div></td><td><div><div><ul><li><p>The operation must support transactions.</p></li><li><p>All operations inside the transaction must belong to the same Connector. (For example <code>jms:listener</code>, <code>jms:consume</code> and <code>jms:publish</code>).</p></li><li><p>All operations must use the same Global Configuration (<code>config-ref</code>).</p></li></ul></div></div></td></tr><tr><td><div><div><p><a href="https://docs.mulesoft.com/mule-runtime/4.12/xa-transactions">Extended Architecture (XA)</a></p></div></div></td><td><div><div><ul><li><p>Involves using a two-phase commit protocol (2PC).</p></li><li><p>Slower but more reliable than Single Resource transactions.</p></li><li><p>Supports nested transactions.</p></li></ul></div></div></td><td><div><div><ul><li><p>The operation must support transactions.</p></li></ul></div></div></td></tr></tbody></table>

## Transactional Actions

A Transactional Action (`transactionalAction`) defines the type of action that operations take
regarding transactions. The following table describes all available transactional actions:

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Action</th><th>Behavior</th><th>Available in</th></tr></thead><tbody><tr><td><div><div><p><code>ALWAYS_BEGIN</code></p></div></div></td><td><div><div><p>Always start a new transaction when receiving a message. If a Single Resource transaction exists, an error occurs. If an XA transaction exists, a nested transaction is created.</p></div></div></td><td><div><div><ul><li><p>Listeners that support transactions</p></li><li><p>Try scope</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>ALWAYS_JOIN</code></p></div></div></td><td><div><div><p>Always expect a transaction to be in progress when a message is received. If there is no transaction, an error occurs.</p></div></div></td><td><div><div><ul><li><p>Operations that support transactions</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>BEGIN_OR_JOIN</code></p></div></div></td><td><div><div><p>If a transaction is already in progress when a message is received, join the transaction if possible. Otherwise, start a new transaction.</p></div></div></td><td><div><div><ul><li><p>Try scope</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>JOIN_IF_POSSIBLE</code></p></div></div></td><td><div><div><p>Join the current transaction if one is available. Otherwise, no transaction is created.</p></div></div></td><td><div><div><ul><li><p>Operations that support transactions</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>INDIFFERENT</code></p></div></div></td><td><div><div><p>Do not treat actions as a transaction.</p></div></div></td><td><div><div><ul><li><p>Try scope</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>NONE</code></p></div></div></td><td><div><div><p>Do not initiate a transaction.</p></div></div></td><td><div><div><ul><li><p>Listeners that support transactions</p></li></ul></div></div></td></tr><tr><td><div><div><p><code>NOT_SUPPORTED</code></p></div></div></td><td><div><div><p>Execute outside any existent transaction.</p></div></div></td><td><div><div><ul><li><p>Operations that support transactions</p></li></ul></div></div></td></tr></tbody></table>

## Configuring a Transaction in the Event Source

You can start a transaction from a Mule event source. In this case, the entire flow becomes a
transaction. This is useful when working with messaging connectors to prevent the consumption of the
message if a problem occurs when processing it, allowing you to retry later (because of the
rollback).

To initiate a transaction from a Mule event source, configure its Transaction type and Transactional
action:

- In Anypoint Studio

  Open the Listener’s **Advanced** tab, and set the **Transaction type** and the **Transactional
  action** values:

  ![A transaction configuration panel with settings for action and type](/mulesoft/current/en-us/mule-runtime/4.12/_images/transaction-config-studio-vm.png)

- In the Configuration XML

  Add the `transactionalAction` element and the `transactionType` element (if necessary), and set
  their values.

  The XML example below illustrates a `vm:listener` event source configured to initiate a Single
  Resource (Local) transaction:

  ```xml
  <?xml version="1.0" encoding="UTF-8"?>
  <mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
  	xmlns="http://www.mulesoft.org/schema/mule/core"
  	xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
  http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
  http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">

  	<vm:config name="VM_Config1" >
  		<vm:queues >
  			<vm:queue queueName="input" />
  			<vm:queue queueName="output" />
  		</vm:queues>
  	</vm:config>

  	<flow name="source-transactionsFlow">
  		<vm:listener config-ref="VM_Config1" queueName="input" transactionalAction="ALWAYS_BEGIN"/>
  		<http:request method="GET" url="www.google.com"/>
  		<vm:publish config-ref="VM_Config1" queueName="output"/>
  	</flow>
  </mule>
  ```

## Configuring a Transaction in a Try Scope

A Mule flow can also begin with a non-transactional connector (such as HTTP) that requires a
transaction within the flow. For example, a Mule flow might accept information from an external Web
service, then transform the data before charging a credit card and saving invoice information to a
database. In such a situation, you use the Try scope to set up a transaction by wrapping the credit
card charge and database commit operations within a transaction to ensure either complete success or
complete failure and rollback.

You can configure a transaction in a Try scope component by setting a Transaction type and
Transactional action:

- In Anypoint Studio

  Open the Try scope’s **General** tab, and set the **Transaction type** and the **Transactional
  action** values:

  ![A transaction configuration interface with settings for action and type](/mulesoft/current/en-us/mule-runtime/4.12/_images/transaction-config-studio.png)

- In the Configuration XML

  Add the `transactionalAction` element and the `transactionType` element (if necessary), and set
  their values.

  In the following XML example the Try scope demarcates a transaction that includes a Database
  operation (`db:insert`) and a VM operation (`vm:publish`). Either both will be applied if the
  entire process succeeds, or none will be applied if an error occurs within the Try scope:

  ```xml
  <?xml version="1.0" encoding="UTF-8"?>
  <mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:db="http://www.mulesoft.org/schema/mule/db"
  	xmlns="http://www.mulesoft.org/schema/mule/core"
  	xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
  	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
  http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
  http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd">
  	<db:config name="Database_Config">
  		<db:derby-connection database="myDb" create="true" />
  	</db:config>
  	<vm:config name="VM_Config">
  		<vm:queues>
  			<vm:queue queueName="myQueue" />
  		</vm:queues>
  	</vm:config>
  	<flow name="transactionsFlow">
  		<try transactionalAction="ALWAYS_BEGIN" transactionType="XA">
  		    <db:insert doc:name="Insert" transactionalAction="ALWAYS_JOIN">
  	                  <db:sql>
  				  INSERT INTO main_flow_audit (errorType, description) VALUES (:errorType, :description)
  	                  </db:sql>
  	                  <db:input-parameters><![CDATA[
  	                     #[{
  	                         'errorType' : 'AUTHENTICATION',
  	                         'description' : 'invalid authentication credentials',
  	                      }]
  	            ]]></db:input-parameters>
  	             </db:insert>
  		     <vm:publish config-ref="VM_Config" queueName="myQueue" transactionalAction="ALWAYS_JOIN"/>
  		</try>
  	</flow>
  </mule>
  ```

## How Transactions Affect Scopes and Routers

When running in a transactional scope, the entire process must run in the same thread. This can
change the way a scope executes, or how a transaction is handled. Below is detailed the behavior of
the scopes and routers you must consider when running in a transactional scope:

### Scopes

- [Async](https://docs.mulesoft.com/mule-runtime/4.12/async-scope-reference): When running within a transaction, the Async scope will still run
  in another thread (remaining asynchronous). However, this means that the entire execution of the
  processors within this scope is out of the transactional scope. Therefore, any error produced
  inside an Async scope does not result in a rollback.

- [Until Successful](https://docs.mulesoft.com/mule-runtime/4.12/until-successful-scope): When running within a transaction, the Until
  Successful scope blocks the thread. This means that the thread used by this execution cannot be
  used to process any other request while the Until Successful scope is performing the delay between
  retries.

- [Parallel Foreach](https://docs.mulesoft.com/mule-runtime/4.12/parallel-foreach-scope): When running within a transaction, the Parallel
  Foreach scope does not execute in parallel. This means it executes as the Foreach scope: the
  second element of the collection is processed after the first one has finished. This does not
  affect the way this scope handles errors.

- [Batch Processing](https://docs.mulesoft.com/mule-runtime/4.12/batch-processing-concept): Since Batch Processing is designed to work on
  parallel as the Async scope, and every record is treated transactionally (with internal Batch
  transactions), the batch execution is not part of the transaction.

### Routers

- [Scatter Gather](https://docs.mulesoft.com/mule-runtime/4.12/scatter-gather-concept): When running within a transaction, Scatter Gather does
  not execute in parallel. This means that the second route is executed after the first one is
  processed, the third after the second one, etc. This does not affect the way this component
  handles errors.

- [Flow Reference](https://docs.mulesoft.com/mule-runtime/4.12/flowref-about): If the flow (or subflow) being executed is running within a
  transaction, the execution of the flow (or subflow) referenced by the Flow Reference component
  continues with the same transaction. If the referenced flow has a Mule event source that begins a
  transaction (For example a `jms:listener` source with `transactionalAction="ALWAYS_BEGIN"`), the
  `transactionalAction` is ignored. The Flow Reference component executes the referenced flow
  components except for its event source.

Any other router or scope (for example, Foreach) continues with the transaction and its behavior is
not modified.

## Error Handling

When an error occurs during a transaction, your application must either handle the error and
continue or perform a rollback.

There are two types of error handlers, which behave differently when an error occurs during a
transaction:

- On Error Propagate

  - If the `on-error-propagate` error handler is inside the `error-handler` scope corresponding to
    the component that began the transaction:

    The transaction is rolled back before executing the processors of the `on-error-propagate`
    scope. This means that the processors inside the error handler do not run within the
    transaction.

  - If the `on-error-propagate` error handler is inside an element that did not start the
    transaction:

    The transaction is not rolled back and the processors inside the `on-error-propagate` error
    handler run within the transaction. Remember that some scopes and routers behave differently
    when executing within a transaction.

- On Error Continue

  The error is handled, the transaction remains active and is able to commit. The processors inside
  the `on-error-continue` run within the transaction.

### Example: Error Occurs in Try Scope

Consider an example in which the event source (`jms:listener`) starts a transaction, which is
continued by the Try scope (`transactionalAction` is set to default, `INDIFFERENT`).

When the error occurs, it is handled by the `error-handler` of the Try scope first. The error is
handled by an `on-error-propagate` error handler, but the transaction is not rolled back because it
was not the Try scope that started the transaction. Only the flow error handler can roll back the
transaction, because the transaction was initiated at flow level (from its event source).

The `jms:publish` operation inside the `on-error-propagate` error handler joins the transaction. The
error is then propagated to the flow `error-handler`, which handles the error with an
`on-error-continue` error handler. The `jms:consume` operation inside the `on-error-continue` error
handler runs within the transaction. Finally, the transaction is committed.

```xml
<flow name="someFlowWithTx">
	<jms:listener config-ref="JMS_Config" destination="test.in" transactionalAction="ALWAYS_BEGIN"/>
	<!-- Processors -->
	<try>
		<raise-error type="APP:SOME"/>
		<error-handler>
			<on-error-propagate>
				<jms:publish config-ref="JMS_Config" destination="test.out" transactionalAction="ALWAYS_JOIN"/>
			</on-error-propagate>
		</error-handler>
	</try>
	<error-handler>
		<on-error-continue>
			<jms:consume config-ref="JMS_Config" destination="test.in2" transactionalAction="ALWAYS_JOIN"/>
		</on-error-continue>
	</error-handler>
</flow>
```

If the `on-error-continue` error handler is replaced with an `on-error-propagate` error handler in
the previous example, then the transaction is rolled back before the execution of the processors. In
this scenario, the configuration is not correct because the `jms:consume` operation cannot join any
transaction.

### Example: Error Occurs in a Referenced Flow

The following example behaves the same as the previous one, but instead of having a Try scope it
uses a Flow Reference and the error occurs in the referenced flow:

```xml
<flow name="someFlowWithTx">
	<jms:listener config-ref="JMS_Config" destination="test.in" transactionalAction="ALWAYS_BEGIN"/>
	<!-- Processors -->
	<flow-ref name="someFlowContinuesTx"/>
	<error-handler>
		<on-error-continue>
			<jms:consume config-ref="JMS_Config" destination="test.in2" transactionalAction="ALWAYS_JOIN"/>
		</on-error-continue>
	</error-handler>
</flow>

<flow name="someFlowContinuesTx">
	<raise-error type="APP:SOME"/>
	<error-handler>
		<on-error-propagate>
			<jms:publish config-ref="JMS_Config" destination="test.out" transactionalAction="ALWAYS_JOIN"/>
		</on-error-propagate>
	</error-handler>
</flow>
```

Because the `someFlowContinuesTx` flow did not initiate the transaction, its error handler does not
roll back the transaction.

### Example: Comparing Error Handlers

This example shows the differences between the `on-error-continue` error handler and the
`on-error-propagate` error handler:

```xml
<flow name="flow1">
	<jms:listener config-ref="JMS_Config" destination="test.in" transactionalAction="ALWAYS_BEGIN"/>
	<raise-error type="APP:SOME"/>
	<error-handler>
		<on-error-continue>
			<try transactionalAction="ALWAYS_BEGIN">
				<logger message="hello"/>
			</try>
		</on-error-continue>
	</error-handler>
</flow>

<flow name="flow2">
	<jms:listener config-ref="JMS_Config" destination="test.in" transactionalAction="ALWAYS_BEGIN"/>
	<raise-error type="APP:SOME"/>
	<error-handler>
		<on-error-propagate>
			<try transactionalAction="ALWAYS_BEGIN">
				<logger message="hello"/>
			</try>
		</on-error-propagate>
	</error-handler>
</flow>
```

In `flow1`, the `on-error-continue` error handler keeps the transaction active, but the Try scope
inside it tries to initiate a new transaction. The configuration is not valid and results in an
error.

In `flow2`, the `on-error-propagate` error handler rolls back the transaction, the processors inside
the `on-error-propagate` error handler are executed, and a new transaction is created. This
configuration is correct.

## See Also

- [Try Scope](https://docs.mulesoft.com/mule-runtime/4.12/try-scope-concept)

- [Reliability Patterns](https://docs.mulesoft.com/mule-runtime/4.12/reliability-patterns)

- [On-Error Scope](https://docs.mulesoft.com/mule-runtime/4.12/on-error-scope-concept)
