13 Coordinating XAResources with the WebLogic Server Transaction Manager

This chapter describes how external, third-party systems can participate in distributed transactions coordinated by the WebLogic Server transaction manager by registering a javax.transaction.xa.XAResource implementation with the WebLogic Server transaction manager. The WebLogic Server transaction manager then drives the XAResource as part of its Two-Phase Commit (2PC) protocol. This is referred to as "exporting transactions."

By exporting transactions, you can integrate third-party transaction managers with the WebLogic Server transaction manager if the third-party transaction manager implements the XAResource interface. With an exported transaction, the third-party transaction manager would act as a subordinate transaction manager to the WebLogic Server transaction manager.

WebLogic Server can also participate in distributed transactions coordinated by third-party systems (sometimes referred to as foreign transaction managers). The WebLogic Server processing occurs as part of the work of the external transaction. The third-party transaction manager then drives the WebLogic Server transaction manager as part of its commit processing. This is referred to as "importing transactions."

Details about coordinating third-party systems within a transaction (exporting transactions) are described in this section. Details about participating in transactions coordinated by third-party systems (importing transactions) are described in Chapter 14, "Participating in Transactions Managed by a Third-Party Transaction Manager." Note that WebLogic Server IIOP, WebLogic Tuxedo Connector (WTC) gateway, and Oracle Java Adapter for Mainframe (JAM) gateway internally use the same mechanism described in these chapters to import and export transactions in WebLogic Server.

This chapter includes the following sections:

Overview of Coordinating Distributed Transactions with Foreign XAResources

In order to participate in distributed transactions coordinated by the WebLogic Server transaction manager, third-party systems must implement the javax.transaction.xa.XAResource interface and then register its XAResource object with the WebLogic Server transaction manager. For details about implementing the javax.transaction.xa.XAResource interface, refer to the Java Platform Enterprise Edition, v 5.0 API Specifications at:

http://docs.oracle.com/javaee/7/api/javax/transaction/xa/XAResource.html

During transaction processing, you must enlist the XAResource object of the third-party system with each applicable transaction object.

Figure 13-1 shows the process for third-party systems to participate in transactions coordinated by the WebLogic Server transaction manager.

Figure 13-1 Distributed Transactions with Third-Party Participants

Description of Figure 13-1 follows
Description of ''Figure 13-1 Distributed Transactions with Third-Party Participants''

Depending on the enlistment mode that you use when you enlist an XAResource object with a transaction, WebLogic Server may automatically delist the XAResource object at the appropriate time. For more information about enlistment and delistment, see Enlisting and Delisting an XAResource in a Transaction. For more information about registering XAResource objects with the WebLogic Server transaction manager, see Registering an XAResource to Participate in Transactions.

Registering an XAResource to Participate in Transactions

In order to participate in distributed transactions coordinated by the WebLogic Server transaction manager, third-party systems must implement the javax.transaction.xa.XAResource interface and then register its XAResource object with the WebLogic Server transaction manager. Registration is required to:

  • Specify the transaction branch qualifier for the XAResource. The branch qualifier identifies the transaction branch of the resource manager instance and is used for all distributed transactions that the resource manager (RM) instance participates in. Each transaction branch represents a unit of work in the distributed transaction and is isolated from other branches. Each transaction branch receives exactly one set of prepare-commit calls during Two-Phase Commit (2PC) processing. The WebLogic Server transaction manager uses the resource name as the transaction branch qualifier.

    A resource manager instance is defined by the XAResource.isSameRM method. XAResource instances that belong to the same resource manager instance should return true for isSameRM. Note that you should avoid registering the same resource manager instance under different resource names (for example, different resource branches) to avoid confusion of transaction branches.

  • Specify the enlistment mode. For a resource manager instance to participate in a specific distributed transaction, it enlists an XAResource instance with the JTA javax.transaction.Transaction object. The WebLogic Server transaction manager provides three enlistment modes: static, dynamic, and object-oriented. Enlistment modes are discussed in greater detail in Enlisting and Delisting an XAResource in a Transaction.

  • Bootstrap the XAResource if the WebLogic Server transaction manager must perform crash recovery. (The JTA Specification does not define a standard API to do so; see the Java Transaction API at http://www.oracle.com/technetwork/java/javaee/jta/index.html).

    The Java Transaction API suggests that the transaction manager is responsible for assigning the branch qualifiers. However, for recovery to work properly, the same transaction branch qualifier must be supplied both at normal processing and upon crash recovery. As the transaction branch qualifier is specified during registration, registration with the WebLogic Server transaction manager is required to support crash recovery and normal transaction processing.

    During recovery, the WebLogic Server transaction manager performs the following tasks:

    • It reads its transaction log records and for those XA resources that participated in the distributed transactions that were logged, it continues the second phase of the 2PC protocol to commit the XA resources with the specified branch qualifier.

    • It resolves any other in-doubt transactions of the XA resources by calling XAResource.recover. It then commits or rolls back the returned transactions (Xids) that belonged to it. (Note that the returned Xids would have the specified branch qualifier.)

      Note:

      Registration is a per-process action (compared with enlistment and delistment which is per-transaction).

Failure to register the XAResource implementation with the WebLogic Server transaction manager may result in unexpected transaction branching behavior. If registration is not performed before the XA resource is enlisted with a WebLogic Server distributed transaction, the WebLogic Server transaction manager uses the class name of the XAResource instance as the resource name (and thus the branch qualifier), which may cause undesirable resource name and transaction branch conflicts.

Each resource manager instance should register itself only once with the WebLogic Server transaction manager. Each resource manager instance, as identified by the resource name during registration, adds significant overhead to the system during recovery and commit processing and health monitoring, increases memory used by associated internal data structures, reduces efficiency in searching through internal maps, and so forth. Therefore, for scalability and performance reasons, you should not indiscriminately register XAResource instances under different transaction branches.

Note that the JTA XAResource adopts an explicit transaction model, where the Xid is always explicitly passed in the XAResource methods and a single resource manager instance handles all of the transactions. This is in contrast to the CORBA OTS Resource, which adopts an implicit transaction model, where there is a different OTS Resource instance for each transaction that it participates in. You should use the JTA model when designing an XAResource.

Each foreign resource manager instance should register an XAResource instance with the WebLogic Server transaction manager upon server startup. In WebLogic Server, you can use startup classes to register foreign transaction managers.

Follow these steps to register the resource manager with the WebLogic Server transaction manager:

  1. Obtain the WebLogic Server transaction manager using JNDI or the TxHelper interface:

    import javax.transaction.xa.XAResource;
    import weblogic.transaction.TransactionManager;
    import weblogic.transaction.TxHelper;
    InitialContext initCtx = ... ; // initialized to the initial context
    TransactionManager tm = TxHelper.getTransactionManager();
    

    or

    TransactionManager tm = (TransactionManager)initCtx.lookup("weblogic.transaction.TransactionManager");
    

    or

    TransactionManager tm = (TransactionManager)initCtx.lookup("javax.transaction.TransactionManager");
    
  2. Register the XA resource instance with the WebLogic Server transaction manager:

    String name = ... ; // name of the RM instance
    XAResource res = ... ; // an XAResource instance of the RM instance
    tm.registerResource(name, res); // register a resource with the standard enlistment mode 
    

    or

    tm.registerDynamicResource(name, res); // register a resource with the dynamic enlistment mode 
    

    or

    tm.registerStaticResource(name, res); // register a resource with the static enlistment mode 
    

Refer to Enlisting and Delisting an XAResource in a Transaction for a detailed discussion of the different enlistment modes. Note that when you register the XAResource, you specify the enlistment mode that is subsequently used, but you are not actually enlisting the resource during the registration process. Actual enlistment should be done with the transaction (not at server startup) using a different API, which is also discussed in detail in Enlisting and Delisting an XAResource in a Transaction.

Each XAResource instance that you register is used for recovery and commit processing of multiple transactions in parallel. Ensure that the XAResource instance supports resource sharing as defined in JTA Specification Version 1.0.1B Section 3.4.6.

Note:

Duplicate registration of the same XAResource is ignored.

You should unregister the XAResource from the WebLogic Server transaction manager when the resource no longer accept new requests. Use the following method to unregister the XAResource:

tm.unregisterResource(name, res); 

Enlisting and Delisting an XAResource in a Transaction

For an XAResource to participate in a distributed transaction, the XAResource instance must be enlisted with the Transaction object. Depending on the enlistment mode, you may need to perform different actions. The WebLogic Server transaction manager supports the following enlistment modes:

Even though you enlist the XAResource with the Transaction object, the enlistment mode is determined when you register the XAResource with the WebLogic Server transaction manger, not when you enlist the resource in the Transaction. See Registering an XAResource to Participate in Transactions.

XAResource.start and end calls can be expensive. The WebLogic Server transaction manager provides the following optimizations to minimize the number of these calls:

  • Delayed delistment:

    Whether or not your XAResource implementation performs any explicit delistment or not, the WebLogic Server transaction manager always delays delisting of any XAResource instances that are enlisted in the current transaction until immediately before the following events, at which time the XAResource is delisted:

    • Returning the call to the caller, whether it is returned normally or with an exception

    • Making a call to another server

  • Ignored duplicate enlistment:

    The WebLogic Server transaction manager ignores any explicit enlistment of an XAResource that is enlisted. This may happen if the XAResource is explicitly delisted (which is delayed or ignored by the WebLogic Server transaction manager as mentioned above) and is subsequently re-enlisted within the duration of the same call.

By default, the WebLogic Server transaction manager delists the XAResource by calling XAResource.end with the TMSUSPEND flag. Some database management systems may keep cursors open if XAResource.end is called with TMSUSPEND, so you may prefer to delist an XAResource by calling XAResource.end with TMSUCCESS wherever possible. To do so, you can implement the weblogic.transaction.XAResource interface (instead of the javax.transaction.xa.XAResource), which includes the getDelistFlag method. For more information, see weblogic.transaction.XAResource in the Java API Reference for Oracle WebLogic Server.

Standard Enlistment

With standard enlistment mode, enlist the XAResource instance only once with the Transaction object. Also, it is possible to enlist multiple XAResource instances of the same branch with the same transaction. The WebLogic Server transaction manager ensures that XAResource.end is called on all XAResource instances when appropriate (as discussed below). The WebLogic Server transaction manager ensures that each branch receives only one set of prepare-commit calls during transaction commit time. However, attempting to enlist a particular XAResource instance when it is already enlisted is ignored.

Standard enlistment simplifies enlistment, but it may also cause unnecessary enlistment and delistment of an XAResource if the resource is not accessed at all within the duration of a particular method call.

To enlist an XAResource with the Transaction object, follow these steps:

  1. Obtain the current Transaction object using the TransactionHelper interface:

    import weblogic.transaction.Transaction; // extends javax.transaction.Transaction
    import weblogic.transaction.TransactionHelper;
    Transaction tx = TransactionHelper.getTransaction();
    
  2. Enlist the XAResource instance with the Transaction object:

    tx.enlistResource(res);
    

After the XAResource is enlisted with the Transaction, the WebLogic Server transaction manager manages any subsequent delistment (as described in Enlisting and Delisting an XAResource in a Transaction) and re-enlistment. For standard enlistment mode, the WebLogic Server transaction manager re-enlists the XAResource in the same Transaction upon the following occasions:

  • Before a request is executed

  • After a reply is received from another server. (The WebLogic Server transaction manager delists the XAResource before sending the request to another server.)

Dynamic Enlistment

With the dynamic enlistment mode, you must enlist the XAResource instance with the Transaction object before every access of the resource. With this enlistment mode, only one XAResource instance from each transaction branch is allowed to be enlisted for each transaction at a time. The WebLogic Server transaction manager ignores attempts to enlist additional XAResource instances (of the same transaction branch) after the first instance is enlisted, but before it is delisted.

With dynamic enlistment, enlistments and delistments of XAResource instances are minimized.

The steps for enlisting the XAResource are the same as described in Standard Enlistment.

Static Enlistment

With static enlistment mode, you do not need to enlist the XAResource instance with any Transaction object. The WebLogic Server transaction manager implicitly enlists the XAResource for all transactions with the following events:

  • Before a request is executed

  • After a reply is received from another server

    Note:

    Consider the following before using the static enlistment mode:
    • Static enlistment mode eliminates the requirement to enlist XAResources. However, unnecessary enlistment and delistment may result, if the resource is not used in a particular transaction.

    • A faulty XAResource may adversely affect all transactions even if the resource is not used in the transaction.

    • A single XAResource instance is used to associate different transactions with different threads at the same time. That is, XAResource.start and XAResource.end can be called on the same XAResource instance in an interleaved manner for different Xids in different threads. You must ensure that the XAResource supports such an association pattern, which is not required by the JTA specification.

    Due to the performance overhead, poor fault isolation, and demanding transaction association requirement, static enlistment should only be used with discretion and after careful consideration.

Commit processing

During commit processing, the WebLogic Server transaction manager either uses the XAResource instances currently enlisted with the transaction, or the XAResource instances that are registered with the transaction manager to perform the two-phase commit. The WebLogic Server transaction manager ensures that each transaction branch receives only one set of prepare-commit calls. You must ensure that any XAResource instance can be used for commit processing for multiple transactions simultaneously from different threads, as defined in JTA Specification Version 1.0.1B Section 3.4.6.

Recovery

When a WebLogic Server server is restarted, the WebLogic Server transaction manager reads its own transaction logs (with log records of transactions that are successfully prepared, but may not have completed the second commit phase of 2PC processing). The WebLogic Server transaction manager then continues to retry commit of the XAResources for these transactions. As discussed in Registering an XAResource to Participate in Transactions, one purpose of the WebLogic Server transaction manager resource registration API is for bootstrapping XAResource instances for recovery. You must ensure that an XAResource instance is registered with the WebLogic Server transaction manager upon server restart. The WebLogic Server transaction manager retries the commit call every minute, until a valid XAResource instance is registered with the WebLogic Server transaction manager.

When a transaction manager that is acting as a transaction coordinator crashes, it is possible that the coordinator may not have logged some in-doubt transactions in the coordinator's transaction log. Thus, upon server restart, the coordinator must call XAResource.recover on the resource managers, and roll back the in-doubt transactions that were not logged. As with commit retries, the WebLogic Server transaction manager retries XAResource.recover every 5 minutes, until a valid XAResource instance is registered with the WebLogic Server transaction manager.

The WebLogic Server transaction manager checkpoints a new XAResource in its transaction log records when the XAResource is first enlisted with the WebLogic Server transaction manager. Upon server restart, the WebLogic Server transaction manager then calls XAResource.recover on all the resources previously checkpointed (removed from the transaction log records after the transaction completed). A resource is only removed from a checkpoint record if it has not been accessed for the last PurgeResourceFromCheckpointIntervalSeconds interval (default is 24 hours). Therefore, to reduce the resource recovery overhead, you should ensure that only a small number of resource manager instances are registered with the WebLogic Server transaction manager.

When implementing XAResource.recover, you should use the flags as described in the X/Open XA specification as follows:

  • When the WebLogic Server transaction manager calls XAResource.recover with TMSTARTRSCAN, the resource returns the first batch of in-doubt Xids.

    The WebLogic Server transaction manager then calls XAResource.recover with TMNOFLAGS repeatedly, until the resource returns either null or a zero-length array to signal that there are no more Xids to recover. If the resource has returned all the Xids in the previous XAResource.recover(TMSTARTRSCAN) call, then it can either return null or a zero-length array here, or it may also throw XAER_PROTO, to indicate that it has finished and forgotten the previous recovery scan. A common XAResource.recover implementation problem is ignoring the flags or always returning the same set of Xids on XAResource.recover(TMNOFLAGS). This causes the WebLogic Server transaction manager recovery to loop infinitely, and subsequently fail.

  • The WebLogic Server transaction manager XAResource.recover with TMENDRSCAN flag to end the recovery scan. The resource may return additional Xids.

Resource Health Monitoring

To prevent losing server threads to faulty XAResources, WebLogic Server JTA has an internal resource health monitoring mechanism. A resource is considered active if either there are no pending requests or the result from any of the XAResource pending requests is not XAER_RMFAIL. If an XAResource is not active within two minutes, the WebLogic Server transaction manager declares it dead. Any further requests to the XAResource are shunned, and an XAER_RMFAIL XAException is thrown.

The two minute interval can be configured using the maxXACallMillis JTAMBean attribute. It is not exposed through the WebLogic Server Administration Console. You can configure maxXACallMillis in the config.xml file. For example:

<Domain>
....
<JTA
   MaxXACallMillis="240000"
/>
....
</Domain>

To receive notification from the WebLogic Server transaction manager and to inform the WebLogic Server transaction manager whether it is indeed dead when the resource is about to be declared dead, you can implement weblogic.transaction.XAResource (which extends javax.transaction.xa.XAResource) and register it with the transaction manager. The transaction manager calls the detectUnavailable method of the XAResource when it is about to declare it unavailable. If the XAResource returns true, then it is not declared unavailable. If the XAResource is indeed unavailable, it can use this opportunity to perform cleanup and re-registration with the transaction manager. For more information, see weblogic.transaction.XAResource in the Java API Reference for Oracle WebLogic Server.

Java EE Connector Architecture Resource Adapter

Besides registering with the WebLogic Server transaction manager directly, you can also implement the Java EE Connector Architecture resource adapter interfaces. When you deploy the resource adapter, the WebLogic Server Java EE container registers the resource manager's XAResource with the WebLogic Server transaction manager automatically.

For more information, see Developing Resource Adapters for Oracle WebLogic Server.

Implementation Tips

The following sections provide tips for exporting and importing transactions with the WebLogic Server transaction manager:

Sharing the WebLogic Server Transaction Log

The WebLogic Server transaction manager exposes the transaction log to be shared with system applications such as gateways. This provides a way for system applications to take advantage of the box-carring (batching) transaction log optimization of the WebLogic Server transaction manager for fast logging. Note that it is important to release the transaction log records in a timely fashion. (The WebLogic Server transaction manager only removes a transaction log file if all the records in it are released). Failure to do so may result in a large number of transaction log files, and could lead to re-commit of a large number of already committed transactions, or in an extreme case, circular collision and overwriting of transaction log files.

The WebLogic Server transaction manager exposes a transaction logger interface: weblogic.transaction.TransactionLogger. It is only available on the server, and it can be obtained with the following steps:

  1. Get the server transaction manager:

    import weblogic.transaction.ServerTransactionManager;
    import weblogic.transaction.TxHelper;
    ServerTransactionManager stm = (ServerTransactionManager)TxHelper.getTransactionManager();
    
  2. Get the TransactionLogger:

    TransactionLogger tlog = stm.getTransactionLogger();
    

The XAResource's log records must implement the weblogic.transaction.TransactionLoggable interface in order to be written to the transaction log. For more information about the weblogic.transaction.TransactionLogger interface and usage of the TransactionLogger interface, see weblogic.transaction.TransactionLogger in the Java API Reference for Oracle WebLogic Server.

Transaction global properties

A WebLogic Server JTA transaction object is associated with both local and global properties. Global properties are propagated with the transaction propagation context among servers, and are also saved as part of the log record in the transaction log. You can access the transaction global properties as follows:

  1. Obtain the transaction object:

    import weblogic.transaction.Transaction;
    import weblogic.transaction.TransactionHelper;
    Transaction tx = TransactionHelper.getTransaction();  // Get the transaction associated with the thread
    

    or

    Transaction tx = TxHelper.getTransaction(xid); // Get the transaction with the given Xid
    
  2. Get or set the properties on the transaction object:

    tx.setProperty("foo", "fooValue");
    tx.getProperty("bar");
    

For more information, see weblogic.transaction.TxHelper in the Java API Reference for Oracle WebLogic Server.

TxHelper.createXid

You can use the TxHelper.createXid(int formatId, byte[] gtrid, byte[] bqual) method to create Xids, for example, to return to the WebLogic Server transaction manager on recovery.

For more information, see weblogic.transaction.TxHelper in the Java API Reference for Oracle WebLogic Server.

Changes in the Resource Registration Name

This release changes the behavior of the resource registration name for XA data source configurations. In previous releases, the JTA registration name was simply the name of the data source. Now, the registration name is a combination of data source name and domain.

All resources registered with JTA now have a corresponding runtime MBean that exposes XA usage statistics for the resource. This altered (qualified) the JMX ObjectName of the MBean, and may impact existing applications that perform a JMX lookup of such a runtime MBean by name. In previous releases, a data source configuration with a name of mydatasource in domain mydomain would have a JTA resource runtime MBean registered under the object name:

com.bea:ServerRuntime=myserver,Name=mydatasource,Type=TransactionResourceRuntime,JTARuntime=JTARuntime

For this release, the new qualified object name is:

com.bea:ServerRuntime=myserver,Name=mydatasource_mydomain,Type=TransactionResourceRuntime,JTARuntime=JTARuntime

The transaction branch qualifier is also derived from the JTA resource registration name. Any pending transaction branches for XA data sources at the time of upgrade may not be recoverable after upgrade. Oracle recommends that no pending transactions are left pending in database resources prior to upgrade. Otherwise, any pending database transactions may need to be resolved manually by a database administrator. See

This release provides a new system property to disable the qualifying of the registration name:

-Dweblogic.jdbc.qualifyRMName=false

FAQs

  • Why does the XAResource's Xid have a branch qualifier, but not the transaction manager's transaction?

    WebLogic Server JTA transaction objects do not have branch qualifiers (for example, TxHelper.getTransaction().getXid().getBranchQualifier() would be null). Since the branch qualifiers are specific to individual resource managers, the WebLogic Server transaction manager only sets the branch qualifiers in the Xids that are passed into XAResource methods.

  • What is the TxHelper.getTransaction() method used for?

    The WebLogic Server JTA provides the TxHelper.getTransaction() API to return the transaction associated with the current thread. However, note that WebLogic Server JTA suspends the transaction context before calling the XAResource methods, so you should only rely on the Xid input parameter to identify the transaction, but not the transaction associated with the current thread.

Additional Documentation about JTA

Refer to the JTA specification 1.0.1B Section 4.1 for a connection-based Resource Usage scenario, which illustrates the JTA interaction between the transaction manager and resource manager. The JTA specification is available at http://www.oracle.com/technetwork/java/javaee/jta/index.html.