Red Hat Training

A Red Hat training course is available for Red Hat Fuse

7.2. JMS XA Resource

Overview

The Apache ActiveMQ implementation of the JMS XA resource supports the two-phase commit protocol and also implicitly supports distributed transactions. To understand how this works, we take a closer look at the interaction between a JMS XA resource and the broker to which it is connected.
Figure 7.2, “JMS XA Resource Connected to Remote Broker” illustrates what happens when a JMS XA resource participates in a transaction that is committed using the two-phase commit protocol. The JMS XA resource is deployed in an application that runs in the Client host and the corresponding Apache ActiveMQ broker is deployed on the Remote host, so that this transaction branch is effectively a distributed transaction.

Figure 7.2. JMS XA Resource Connected to Remote Broker

JMS XA Resource Connected to Remote Broker

XA two-phase commit process

The two-phase commit shown in Figure 7.2, “JMS XA Resource Connected to Remote Broker” consists of the following steps:
  1. Immediately after the transaction begins, the transaction manager invokes start() on the JMS XA resource, which indicates that the resource should initialize a new transaction. The JMS XA resource now generates a new transaction ID and sends it over the network to the remote broker.
  2. The JMS XA resource now forwards all of the operations that arise during a JMS session (for example, messages, acknowledgments, and so on) to the remote broker.
    On the broker side, the received operations are not performed immediately. Because the operations are happening in a transaction context and the transaction is not yet committed, the broker buffers all of the operations in a transaction store (held in memory, initially). Messages held in the transaction store are not forwarded to JMS consumers.
  3. In a two-phase commit process, the first phase of completing the transaction is where the transaction manager invokes prepare() on all of the participating XA resources. At this stage, the JMS XA resource sends the prepare() operation to the remote broker.
    On the broker side, when the transaction store receives the prepare() operation, it writes all of the buffered operations to disk. Hence, after the prepare phase, there is no longer any risk of losing data associated with this transaction branch.
  4. The second phase of completing the transaction is where the transaction manager invokes commit() on all of the participating XA resources. The JMS XA resource sends the commit() operation to the remote broker.
    On the broker side, the transaction store marks this transaction as complete. The pending operations are now executed and any pending messages can now be forwarded to JMS consumers.

Embedded MQ broker

Although Apache ActiveMQ supports a remote connection between the JMS XA resource and the broker, this is not the most efficient or reliable way to set up a transactional application. A network connection usually introduces significant latency and any communication delays between the JMS XA resource and the broker would affect all of the other participants in the transaction.
A more efficient approach would be to embed a broker in the same JVM as the JMS XA resource on the Client host, as shown in Figure 7.3, “JMS XA Resource Connected to Embedded Broker”. In this scenario, an additional broker is deployed on the Client host, preferably running in the same JVM as the JMS XA resource (that is, in embedded mode). Now all of the resource-to-broker communication is localized and runs much faster. It still might be necessary to forward messages to a remote broker, but this communication has no effect on the XA transactions.

Figure 7.3. JMS XA Resource Connected to Embedded Broker

JMS XA Resource Connected to Embedded Broker

Default MQ broker

By default, a standalone JBoss Fuse container already has an MQ broker deployed in it. If you deploy a JMS XA resource into this container, you can communicate efficiently with the default broker through the JVM, by connecting through the broker URL, vm:amq.