3.1. The XAResource
interface
Some transaction specifications and systems define a generic resource which can be used to register arbitrary resources with a transaction, the JTA is much more XA-specific. Interface javax.transaction.xa.XAResource
is a Java mapping of the XA interface. The XAResource
interface defines the contract between a ResourceManager
and a TransactionManager
in a distributed transaction processing environment. A resource adapter for a ResourceManager
implements the XAResource
interface to support association of a top-level transaction to a resource such as a relational database.
3.1.1. Extended XAResource
control
By default, whenever an XAResource
object is registered with a JTA-compliant transaction service, there is no way to manipulate the order in which it is invoked during the two-phase commit protocol, with respect to other XAResource
objects. JBoss Transactions, however, provides support for controlling the order via the two interfaces com.arjuna.ats.jta.resources.StartXAResource
and com.arjuna.ats.jta.resources.EndXAResource
. By inheriting your XAResource
instance from either of these interfaces, you control whether an instance of your class is invoked first or last, respectively.
Only one instance of each interface type may be registered with a specific transaction.
The ArjunaCore Development Guide discusses the Last Resource Commit optimization (LRCO), whereby a single resource that is only one-phase aware, and does not support the prepare
phase, can be enlisted with a transaction that is manipulating two-phase aware participants. This optimization is also supported within the JBoss Transactions.
In order to use the LRCO, your XAResource
implementation must extend the com.arjuna.ats.jta.resources.LastResourceCommitOptimisation
marker interface. A marker interface is an interface which provides no methods. When enlisting the resource via method Transaction.enlistResource
, JBoss Transactions ensures that only a single instance of this type of participant is used within each transaction. Your resource is driven last in the commit protocol, and no invocation of method prepare
occurs.
By default an attempt to enlist more than one instance of a LastResourceCommitOptimisation class will fail and false will be returned from Transaction.enlistResource. This behavior can be overridden by setting the com.arjuna.ats.jta.allowMultipleLastResources to true. However, before doing so you should read the section on enlisting multiple one-phase aware resources.
You need to disable interposition support to use the LCRO in a distributed environment. You can still use implicit context propagation.
3.1.1.1. Enlisting multiple one-phase-aware resources
One-phase commit is used to process a single one-phase aware resource, which does not conform to the two-phase commit protocol. You can still achieve an atomic outcome across resources, by using the LRCO, as explained earlier.
Multiple one-phase-aware resources may be enlisted in the same transaction. One example is when a legacy database runs within the same transaction as a legacy JMS implementation. In such a situation, you cannot achieve atomicity of transaction outcome across multiple resources, because none of them enter the prepare
state. They commit or roll back immediately when instructed by the transaction coordinator, without knowledge of other resource states and without a way to undo if subsequent resources make a different choice. This can result in data corruption or heuristic outcomes.
You can approach these situations in two different ways:
If neither of these options is viable, JBoss Transactions support enlisting multiple one-phase aware resources within the same transaction, using LRCO, which is discussed in the ArjunaCore Development Guide in detail.
Even when this support is enabled, JBoss Transactions issues a warning when it detects that the option has been enabled: You have chosen to enable multiple last resources in the transaction manager. This is transactionally unsafe and should not be relied upon.
Another warning is issued when multiple one-phase aware resources are enlisted within a transaction: This is transactionally unsafe and should not be relied on.
To override the above-mentioned warning at runtime, set the CoreEnvironmentBean.disableMultipleLastResourcesWarning
property to true
. You will see a warning that you have done this when JBoss Transactions starts up and see the warning about enlisting multiple one-phase resources only the first time it happens, but after that no further warnings will be output. You should obviously only consider changing the default value of this property (false) with caution.