Using XA Transactions
Note: This section is primarily intended for application architects and intermediate to advanced programmers who intend to build their own XA solution rather than using the available Solace JEE Connector Architecture (JCA) Resource Adapter. It is also provided for those application architects and programmers who want to realize some of the underlying interfaces and constructs used by XA transactions.
The Solace JMS implementation Version 7.1 and greater supports the Java Transaction API (JTA) and the
javax.transaction.xa.XAResource interface. The XAResource interface provides a Java mapping of the XA interface that follows the X/Open CAE Specification.
By supporting the XAResource interface, a client can use the Solace JMS implementation to create an XA Session in which it can create transaction branches (also referred to simply as transactions in this section) to publish and/or receive a series of Guaranteed messages.
The messages published and/or received in a transaction branch within an XA Session are contained as single atomic units. This behavior is similar to a local transacted Session (refer to Using Transacted Sessions), however, an XA transaction branch differs in that it may be part of a larger, distributed transaction (also known as a global transaction) that involves a set of two or more related transaction branches from separate networked Java resources that are managed in a coordinated way. Within a distributed transaction, those networked resources have no knowledge of or means of communicating with the other resources involved.
A Transaction Manager, a software entity that is often associated with a Java Platform Enterprise Edition (Java EE) application server, uses an XAResource object obtained for each XA Session that will participate in a distributed transaction. Using these XAResource objects, the Transaction Manager can manage the transaction branches involved in the distributed transaction. (The XAResource relies on Xids that uniquely identify each XA transaction and the global transaction they are associated with.)
A Transaction Manager can, in a coordinated fashion, instruct each XAResource to perform specific actions for their respective transaction branches according to a two-phase commit process used for distributed transactions.
- In the first phase, the Transaction Manager directs each resource in the distributed transaction to prepare their transactions for a future commit.
- In the second phase, the Transaction Manager then either directs each resource to do one of the following actions:
- Commit their respective transaction branches. In this case, the work performed by all of the transactions is committed and the entire transaction is atomically committed.
- Roll back their transactions if one or more resources reported that they were unable to prepare their transaction branches for a commit. In this case, none of the work performed in the transactions is committed.
Note: Solace does not offer a Transaction Manager. However, to allow administrators to integrate Solace PubSub+ with Java EE application server environments, a Solace JCA v1.5 resource adapter for some Application Server environments is available. For more information, contact Solace support.
As a Java mapping of XA, JTA differs from the XA specification in how it handles threading. XA has a concept of “thread of control” that dictates that a given transaction can only be accessed by a single thread, or if it is to be migrated to another thread, that special operations must be performed on the transaction. JTA instead creates an XAResource object that assumes the role of the XA thread of control. Therefore, in JTA, a transaction is not bound to a processing thread, but instead to an XAResource, and the XAResource must provide thread safety where necessary. By using an XAResource, the thread migration considerations for XA are not present for JTA.
Another simplification made by JTA is that the asynchronous operations described in the XA specification are not supported—XA may have an option to asynchronously complete an operation, but in JTA the operation always blocks. The lack of asynchronous operation support in JTA is not overly limiting because of the use of multi-threading in current Java applications.