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](https://access.redhat.com/webassets/avalon/d/Red_Hat_JBoss_Fuse-6.1-Transaction_Guide-en-US/images/da95d816ac9ba1f90b57d29401d6afb7/xa_jms_02.png)
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:
- 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. - 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.
- 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 theprepare()
operation to the remote broker.On the broker side, when the transaction store receives theprepare()
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. - 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 thecommit()
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](https://access.redhat.com/webassets/avalon/d/Red_Hat_JBoss_Fuse-6.1-Transaction_Guide-en-US/images/97ff18487cf8afcd738f187366f83708/xa_jms_03.png)
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
.