---
schema_version: "1"
id: 670eced95cfeea4e1321036b3b90df6c1664a7584a04999511b1b872b2f5630c
title: Transactional Message Sources
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-sdk/latest/sources-transactions.md
canonical_url: https://docs.mulesoft.com/mule-sdk/latest/sources-transactions
source_site: docs.mulesoft.com
content_type: documentation
content_hash: d54d88096bc33a2c46c34b8203001f153d0b7375234adfc4131c059f995a0252
description: MuleSoft Documentation Site
release: "1.13"
latest: true
---
---
product: Mule SDK
version: 1.13
is-latest-version: true
keywords: mule, sdk, sources, listener, triggers, transactions
---

# Transactional Message Sources

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

Just like operations, Message Sources support transactions. Examples of Message Sources include the
JMS and VM connector listeners. Both listeners take messages out of a queue and push it to a Flow.
If the message processing is successful, the transaction is committed. Otherwise, the transaction is
rolled back, and the message goes back to the queue.

To be transactional, a Message Source needs to operate over a connection type that implements the
`TransactionalConnection` interface, just like operations. XA transactions are also supported
automatically if the connection implements `XATransactionalConnection`.

Example: Transactional Message Source

```java
public class TransactionalSource extends Source<Serializable, Void> {

  @Connection
  private ConnectionProvider<MyTransactionalConnection> connectionProvider;

  ....
}
```

## Message Source Transactional Actions

When a Message Source is transactional, a synthetic parameter named `transactionalAction` is
automatically added to it. That parameter is an `enum` type that can take these values:

- ALWAYS\_BEGIN: Ensures that a new transaction is created for each invocation.

- NONE: Indicates that the source will not start any transaction and will not participate of one
  that is opened in the flow.

## Message Source Transaction Types

When the source supports XA transactions, a `transactionType` parameter is added. This parameter can
take these values:

- LOCAL: Starts a regular transaction.

- XA: Starts an XA transaction instead.

## Handling Transactions

In the SDK, transactions are modeled through Connections. So each transaction requires a different
connection instance. This is because Message Sources need to support parallelism, and the same
connection cannot serve two different transactions at the same time.

This requires a model different from that of the HTTP Listener example used elsewhere in the SDK
documentation. So, consider this oversimplified example that uses the `<vm:listener />` from the VM
Connector:

```java
public VMListener extends Source<Serializable, VMMessageAttributes> {

	@Connection
	private ConnectionProvider<QueueSession> sessionProvider;

	@Override
  public void onStart(SourceCallback<Serializable, VMMessageAttributes> sourceCallback) throws MuleException {
		while(notStopped()) {
			QueueSession session =  sessionProvider.connect(); (1)
      CallbackContext ctx = callback.createContext(); (2)
			TransactionHandle status = ctx.bindConnection(session); (3)

			try {
				callback.handle(session.poll(), ctx); (4)
			} catch (Exception e) {
				status.rollback();
			}
		}
	}

	@OnSuccess
	public void onSuccess(SourceCallbackContext context) {
		handleSuccess(context.getConnection()); (5)
	}

	@OnError
	public void onError(SourceCallbackContext context, Error error) {
		handleError(context, error);
	}
}
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>Multiple connections are obtained.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>For each connection, a new <code>CallbackContext</code> is created.</td></tr><tr><td><i data-value="3"></i><b>3</b></td><td>Each connection is registered with the context through the <code>bindConnection()</code> method in the <code>SourceCallbackContext</code> that was just created.</td></tr><tr><td><i data-value="4"></i><b>4</b></td><td>The context is passed to the <code>handle</code> method.</td></tr><tr><td><i data-value="5"></i><b>5</b></td><td>The connection will later be available for all the <code>onSuccess</code>, <code>onError</code>, and <code>onTerminate methods</code>, through the <code>SourceCallbackContext.getConnection()</code> method.</td></tr></tbody></table>

Because the connection has been bound to the context, the runtime will automatically close the
connection when needed. If the connection is transactional and the source is also configured to be
transactional, then calling the `bindConnection()` method will automatically start the transaction
on that connection. Also if the connection is transactional, the runtime will automatically commit
the transaction after the `onSuccess()` method or roll it back after the `onError()` method.

> [!TIP] Notice that in this case, the transaction needs to be started BEFORE polling any message
> from the queue. It is a good practice to call `bindConnection()` immediately after the connection
> has been obtained.

## Custom Transaction Handling

Some connectors might need to provide custom transaction handling. For example, suppose that in the
case of an error, you want to publish an error response. In that case, you need the transaction to
be committed, because if it gets rolled back, the response will never reach its destination.

Example: Custom Transaction Handling

```java
  @OnError
  public void onError(SourceCallbackContext context, Error error) {
    ctx.getConnection().publish(buildErrorResponse(error)); (1)
    ctx.getTransactionHandle().commit(); (2)
  }
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>The connection is still in an open state when the <code>onSuccess()</code> and <code>onError()</code> methods are executed.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>The context has a <code>TransactionHandle</code> that allows you to manually manipulate the transaction. If you manually resolve the transaction, the runtime will respect your wishes and not do it for you later. You do not need to do this for the most common use cases.</td></tr></tbody></table>
