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 11 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.
The two-phase commit shown in Figure 11 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 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.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.
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 12. 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.
Example 15 gives an example of how to embed a Apache ActiveMQ
broker using Spring XML. This broker configuration should be deployed alongside the
application that creates the XA transactions. To connect to this embedded broker, you
would use the URI, vm:local.
Example 15. Embedded Broker Configured in Spring XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core" ...>
...
<!-- Local ActiveMQ broker instance -->
<amq:broker brokerName="TxXaDemo">
<amq:persistenceAdapter>
<amq:kahaDB directory="txXaDemo-data"/>
</amq:persistenceAdapter>
<amq:transportConnectors>
<amq:transportConnector name="openwire" uri="tcp://localhost:51616"/>
<amq:transportConnector name="vm" uri="vm:local"/>
</amq:transportConnectors>
</amq:broker>
...
</beans>









