Soumyajit Sinha

Oct 12, 20215 min

How to Handle Single and XA (Extended Architecture) Transactions in MuleSoft

Updated: Aug 31, 2023

"Transaction" is a word that is used way too frequently in our daily lives. We use it whenever we are engaged in purchasing or selling any commodity. In our daily lives, a transaction signifies an instance of buying or selling something. Also, a transaction can be deemed as completed only upon the overall completion of the buying/selling activity along with the monetary affair associated with it.

In the software industry, we use the word ‘transaction’ in multiple areas. Predominantly, it is used while discussing SQL queries. Transactions make up a very important component of any software development life cycle (SDLC). Let’s see how transactions are changing lives!

A transaction is a group of operations where all the steps are needed to be successful to commit a result. If any one of the intermediate steps fail, the whole chain of steps fails collectively.

Let’s understand it using a pictorial reference.

Let’s consider a case where we have a chain of steps that represents the following:

We want all the steps to be completed collectively or else we want none of them to happen. In layman’s terms, we want the event to be committed only if all the steps are successful. If any intermediate step fails, we do not want the event to be committed and we do not want any step to be actioned upon.

In the above picture, we have encapsulated these 4 steps in a transaction. The first diagram starts and completes without any errors and gets committed.

But in the second diagram, we can see that in step 2 we encountered a certain error. Now, we don’t want the event to be committed. This is made possible by the transaction action. It will make sure that all the steps are rolled back to the initial state from which the event was kicked off.

Now that we are clear on what transaction is and how it helps in software development, let’s indulge ourselves in bringing it to life in MuleSoft.

MuleSoft supports two types of transactions:

  1. Single resource

  2. XA transactions (Extended Architecture)

Let's talk about them in detail.

Single Resource transactions

Let's consider a Mule flow where we are dealing with a single mode of data transaction. Consider our flow is having only JDBC affairs or JMS activities or VM Queues.

We have created a flow in which we are dealing with 2 tables connecting to the same database. This is how the flow looks like:

Here, the following database actions are carried out:

Here, we have encapsulated all the JDBC components within a TRY block.

Why use the TRY block?

Try block is helping us to enforce the transaction on the JDBC operations by acting as the initiator of a transaction thread. The JDBC components simply connect themselves to the transaction initiated by the try component.

In a try block, you can set how you want to deal with transaction action.

The try-block provides us the following transaction actions:

For more information on the Transactional Actions, please refer to the official documentation.

Once you have defined the transaction action, you can go ahead and set the transaction type.

The try-block provides us the following transaction actions:

In our case, since we are dealing with Single Resource (only JDBC operation), we will be selecting the LOCAL transaction type and we will let the try-block initiate the transaction.

Once the transaction has been kicked off by the try block, all we need to do is to instruct our JDBC components to JOIN this transaction. We can do that simply by going to the “advanced” section of the JDBC operator.

We will select “ALWAYS_JOIN” as the transactional action so that it joins the transaction initiated by the try block earlier. We will be selecting the same option for all our JDBC components.

Once this is done, we can go ahead and deploy our code.

Extended Architecture transactions

Let’s consider a case when we need to deal with multiple data exchange sources. For example, if we need to use a JMS broker along with a JDBC operation and VM queues and we need all of these operations to be performed atomically.

We want all these operations to be performed following the ACID (Atomicity, Consistency, Isolation & Durability) concept.

The XA transaction follows a 2-Phase-Commit protocol.

The first phase of the 2PC is used to check whether all the actions/steps (we can consider these steps to be our JDBC/JMS components) in a transaction have been successfully completed.

If all of them pass or get completed, the transaction manager commits the transaction and writes the corresponding completion logs which can be found in a file with a name ending with “tx-logs” in the .mule folder of your workspace directory.

If any of the components fail execution, the transaction manager rolls back the entire transaction.

We will be using Bitronix Transaction Manager as our transaction manager to accomplish this. We can add this in our Global Elements section in Anypoint Studio.

To add Bitronix Transaction Manager, head on to the Global Elements section and search for Bitronix (left image). Once done, another window (right image) will pop up. Click on “OK” and you are all set!

Let’s try this out in Anypoint Studio. This is how the flow will look like in this case:

Here, the following database actions are carried out:

Compared to what we have done in our implementation of Single Resource transaction, we will do the same thing with the try block, JDBC & JMS components. The only difference is that we have to intimate Mule that we will be using XA transactions.

To do that, we have to select XA as “transaction type” in the Try scope settings.

For JDBC & JMS components, this is configurable in their Global Settings.

In the Database connection config palette, we can head to the “transactions” section where we will have a tick-box to turn the XA transaction on.

In the JMS connection config palette, we need to scroll down to the “Connection Factor” section. Select “Edit inline” for the “Factory configuration”. Then we will have a tick-box to turn the XA transaction on.

Note: For JMS Connection, XA will not work when caching is activated. Please select “No caching” as the Caching Strategy and then click on “Test Connection…” to see whether the connection is successful or not.

We will select “ALWAYS_JOIN” as the transactional action so that it joins the transaction initiated by the try block earlier. We will be selecting the same option for all our JDBC and JMS components.

Once this is done, we can go ahead and deploy our code.

So, now we have the knowledge of what a transaction is and how to set up one in MuleSoft. Apart from that, we have talked about the various kinds of transactions and how to consider one based on the requirement.

Following this up will be an article in which we will take a deeper dive into other intricacies of transactions.

Thank you!!

    16720
    10