IBM WebSphere Developer Technical Journal: Configuring and using XA in a middleware environment

Basics for administrators and application programmers

In today's world of transactions, XA standards are a widely used method for implementing the two-phase commit protocol for achieving reliability, ACID properties, logging, and recovery. Many middleware and database products adhere to the XA protocol to achieve transactional capabilities while interoperating between middleware and resource managers. This article provides a brief overview of what distributed transaction processing (DTP) and XA are all about, explaining concepts such as static and dynamic registration, XA switches, switch-load files, and more, then explains how you can configure various products (IBM® and non-IBM) as XA compliant resource managers in a middleware environment. The article concludes with potential coding restrictions and considerations that could be imposed in an XA environment.

Ajay Sood (, Advisory Software Engineer, IBM Global Services, Bangalore, India

Ajay Sood is an Senior Software Engineer at IBM in Bangalore, India. He has been with IBM for more than 13 years, and has been a developer on such product development team efforts as DB2 DataLinks, and TXSeries-CICS. His experiences include work in transaction processing, middleware, and system programming on UNIX platforms.

04 April 2007

Also available in Chinese

From the IBM WebSphere Developer Technical Journal.


To set the stage for a discussion on XA transaction processing in a variety of middleware environments, let's begin with some definitions.

Transaction processing

A transaction is a set of operations that transforms data from one consistent state to another. This set of operations is an indivisible unit of work, and in some contexts, is also called a logical unit of work. Transactions provide what are known as the ACID properties:

  • Atomicity: Either all steps that are part of the transaction happen or none will happen. If one part of the transaction fails, the entire transaction fails.

  • Consistency: A transaction preserves all the invariant properties (such as integrity constraints) defined on the data. Upon completion of a successful transaction, the data will again be in a consistent state.

  • Isolation: Each transaction should appear to execute independently of other transactions that might be executing concurrently. The effect of executing a set of transactions serially should be the same as that of running them concurrently. This requires two things:

    • During the course of a transaction, the intermediate (possibly inconsistent) state of the data should not be exposed to other transactions.
    • Two concurrent transactions should not be able to operate on the same data.
  • Durability: After a transaction completes successfully, the changes should survive subsequent failures. Here, persistence is the key.

For example, consider a transaction that transfers money from one account to another. Such a transfer involves two parts: money deducted from one account and deposited in the other. Atomicity requires that both withdrawal and deposit should happen in one go, or neither must occur. If multiple requests are processed against an account at the same time, they must be isolated so that only a single transaction can affect the account at one time. If the bank's central computer fails just after the transfer, the correct balance must still be shown when the system becomes available again; the change must be durable. Note that consistency is a function of the application; if money is to be transferred from one account to another, the application must subtract the same amount of money from one account that it adds to the other account.

A distributed transaction is one that runs in multiple processes, usually on several machines. Each process works for the transaction. Like local transactions, distributed transactions must adhere to the ACID properties, and does so by using two features:

  • Recoverable processes log their actions and thus can restore earlier states if a failure occurs. Recoverable processes can store two types of information: transaction state information and descriptions of changes to data. This information enables a process to participate in a two-phase commit and ensures isolation and durability.

  • A commit protocol enables multiple processes to coordinate the committing or aborting of a transaction. The most common commit protocol is the two-phase commit protocol. As it is named, the two-phase commit protocol involves two phases:

    • In the prepare phase, the coordinator sends a message to each process in the transaction, asking each process to prepare to commit. When a process prepares, it guarantees that it can commit the transaction and makes a permanent record of its work. If a process cannot prepare, it must abort.

    • In the commit phase, the coordinator tallies the responses. If all participants are prepared to commit, the transaction commits; otherwise, the transaction aborts. In either case, the coordinator informs all participants of the result. In the case of a commit, the participants acknowledge that they have committed. Committed changes to data are made permanent. This ensures that a successful transaction is reflected as a permanent change to a database and survives hardware and software errors.

    In each transaction, one process acts as the coordinator, overseeing the activities of the other participants in the transaction to ensure a consistent outcome.


The XA standards, set forth by the Open Group's X/Open Distributed Transaction Processing (DTP) model, define the interfaces between the transaction manager, application program, and the resource manager to achieve the two-phase commit in a DTP environment:

  • The application program implements the desired business function. It specifies a sequence of operations that involve resources, such as databases. An application program defines the start and end of a global transaction, accesses resources within transaction boundaries, and usually decides whether to commit or roll back each transaction.

  • The transaction manager manages global transactions and coordinates the decision to commit them or roll them back, thus ensuring their atomicity. The transaction manager also coordinates recovery activities of the resource managers when necessary, such as after a component failure.

  • The resource manager manages a certain part of the computer's shared resources. Many other software entities can request access to the resources from time to time, using services that the resource managers provide. Some resource managers manage a communications resource.

Table 1: Services provided from an implementation of the XA specification
ax_regRegister a resource manager with a transaction manager.
ax_unregUnregister a resource manager with a transaction manager.
xa_closeTerminate the application program's use of a resource manager.
xa_commitTell the resource manager to commit a transaction branch.
xa_completeTest an asynchronous xa operation for completion.
xa_endDisassociate a thread from a transaction branch.
xa_forgetPermit the resource manager to discard its knowledge of a heuristically-completed transaction branch.
xa_openInitialise a resource manager for use by an application program.
xa_prepareAsk the resource manager to prepare to commit a transaction branch.
xa_recoverGet a list of transaction identifiers (XIDs) that the resource manager has prepared or heuristically completed.
xa_rollbackTell the resource manager to roll back a transaction branch.
xa_startStart or resume a transaction branch; associate an XID with future work that the thread requests of the resource manager.

The ax_ routines let a resource manager call a transaction manager; all transaction managers must provide these routines. The xa_ routines are supplied by resource managers operating in the DTP environment and called by transaction managers. When an application program calls a transaction manager to start a global transaction, the transaction manager can use the xa_ interface to inform resource managers of the transaction branch.

Types of registration

Registration is the process of informing the transaction manager about the resource managers that could be involved in a transaction. There are two types of registration:

  • In static registration, the transaction manager involves all the resource managers that are registered with it, even if a resource manager does not have a role to play in a transaction branch.

  • In dynamic registration, only those resource managers which register with the transaction manager get involved in the transaction branch. The resource managers register with the transaction manager using the ax_ routines. Dynamic registration is usually the preferred method due to performance benefit of having the xa calls flow only to the resource managers that are involved in the transaction.

Useful structures when working with an XA-enabled transaction manager

XA switch

A transaction manager can add or remove interactions to or from a resource manager by simply controlling the set of resource managers linked to executable modules. Each resource manager must provide a switch that gives the transaction manager access to the resource manager's xa_ routines. This lets the administrator change the set of resource managers linked with an executable module without having to recompile the application.

XA-enabled databases supply a structure called the XA switch (xa_switch_t), through which an XA transaction manager accesses the various XA functions supported by that database. This structure contains the resource manager's name, non-null pointers to the resource manager's entry points, a flag, and version number. These non-null pointers to entry points implement the xa_ routines. Among other things, the flags tell if the resource manager supports dynamic registration or not.

The xa_switch_t is represented like this:

struct xa_switch_t {
char name[RMNAMESZ]; 				/* name of resource manager */
long flags; 					/* options specific to the resource manager */
long version; 					/* must be 0 */
int (*xa_open_entry)(char *, int, long); 		/* xa_open function pointer */
int (*xa_close_entry)(char *, int, long); 		/* xa_close function pointer */
int (*xa_start_entry)(XID *, int, long); 		/* xa_start function pointer */
int (*xa_end_entry)(XID *, int, long); 		/* xa_end function pointer */
int (*xa_rollback_entry)(XID *, int, long); 		/* xa_rollback function pointer*/
int (*xa_prepare_entry)(XID *, int, long); 		/* xa_prepare function pointer */
int (*xa_commit_entry)(XID *, int, long); 		/* xa_commit function pointer */
int (*xa_recover_entry)(XID *, long, int, long); 	/* xa_recover function pointer */
int (*xa_forget_entry)(XID *, int, long); 		/* xa_forget function pointer */
int (*xa_complete_entry)(int *, int *, int, long);	/* xa_complete function pointer*/

Switch-load file

The transaction manager loads the XA switch structure at run time. The code that does this is known as a switch-load file. The switch-load file could be provided by either the transaction manager or the resource manager, and can optionally provide code to handle the errors returned by the XA routines.

Here is sample code for implementing a switch-load file:

#include <xa.h>
		/* This file, provided by the transaction manager will provide 
		declarations for various constants like XA errors etc. */
extern struct xa_switch_t db2xa_switch;
		/* xa_switch structure provided by the resource manager, DB2 in 
		this example code */
extern struct xa_switch_t TM_xa_switch;
		/* a replacement switch provided by the transaction manager. The 
		functions provided by the replacement switch provide wrappers to 
		the xa functions provided by the resource manager along with 
		enhanced functionality like error handling for the xa errors. */
extern struct xa_switch_t *tm_xa_switch;  

extern void tm_xa_init();

struct xa_switch_t * TM_XA_Init(void)
    tm_xa_switch = "&db2xa_switch;

For example

    TM_xa_switch->flags = tm_xa_switch.flags ;

		/* A sample function implementation for the replacement switch */

TM_xa_open(xhar * open_string, int rmid, long i1)
    int ret;

    ret  = tm_xa_switch->xa_open_entry(open_str, rmid, i1);
		/* call to the resource manager specific function */
    if (ret != OK)
		/* Take transaction manager specific action */


TXSeries® is one example of middleware that can communicate using XA protocol to a variety of resource managers, such as DB2®, Oracle®, WebSphere® MQ, Informix®, and Sybase. The next section describes some of the common configuration steps needed to use these resource managers with different transaction managers.

Preparing to use an application in an XA environment

There are four major preparatory steps you must perform before using an application in an XA environment. The next sections list some key highlights for these four steps in middleware environments using different database or messaging products as a resource manager. Although the configuration is generally similar for all, this information will help you avoid some tricky differences between different product configurations. (See the documentation for the specific product(s) you use for detailed instructions.)

For all, there are four general steps:

  1. Configure the transaction manager. When configuring the transaction manager in your XA environment, these parameters are of particular importance:

    • Object identifier: Identifies the resource manager to the transaction manager.
    • XA Open String: String to be passed to the xa_open call. The data in the string is product-specific, and is used for passing information needed for authentication, such as user IDs and passwords.
    • Thread of control: Tells if the operations in a transaction need to be serialized in the process, or if multiple threads in a process can participate in the transaction branch. If the thread of control is a process, only one thread from a process is allowed to participate in the transaction. For some resource managers like DB2, this parameter is part of the XA Open string.
    • Switch load file: Name of the switch load file to use.
  2. Prepare the resource manager. This involves granting the relevant privileges to the user who is trying to run the transactions that involve the particular resource manager.

  3. Build the switch-load file. You needs to make sure that the relevant switch-load file is built and placed in a proper path for the transaction manager to load along with the application program.

  4. Build the application. The application needs to be built, along with the relevant libraries provided by the resource manager installation. The libraries to be linked will depend on the language of the application, and whether the application is a 32 bit or 64 bit application. In addition, resource managers might occasionally provide something very specific for a particular transaction manager. Building an embedded SQL C application has two steps :

    1. Precompile the file containing the SQLstatements to generate the C code.
    2. Compile the generated C file to get the executables.

With a general understanding of these four steps, let's outline some of the key differences in how these steps are executed with these different resource managers:

Resource manager: DB2 (Version 8.2 and 9)

  1. Configure the transaction manager

    A typical XA open string in DB2 uses the following format:

    databaseName[,userName,passWord], [toc]


    • databaseName is the name of the database. If you have explicitly cataloged an alias name after database creation, use the alias name.
    • userName is an operating system user ID. Specify a user ID if you do not want the region to connect to the database using some default user ID.
    • passWord is the password for the userName user ID.
    • toc indicates whether the thread of control is a process or a thread.

    The name value pairs for userName, passWord, and toc are optional.

  2. Prepare the resource manager

    Update the configuration parameters using:

    db2 update dbm cfg using TP_MON_NAME <tp_specific_name>


    • tp_specific name is "CICS" if the transaction manager is CICS. This parameter is required to improve performance of DB2 when operating with the particular transaction manager.
  3. Build the switch-load file

    DB2 provides dynamic registration by default:

    $(COMPILER) -v –I($TM_INSTALL_PATH)/include \
    db2xa.c \
    -o db2xa \
    -eTM_XA_Init \
    -L($TM_INSTALL_PATH)/lib \
    -L$(DB2DIR)/lib \

    For example, for TXSeries on AIX:

    TM_INSTALL_PATH = /usr/lpp/cics
    TM_REPLACEMENT_SWITCH_FILE = regxa_swxa.o 
    /* This file provides implementation for functions like TM_xa_open, TM_xa_close etc. */

    The switch-load file is db2xa, which will help load the DB2 switch structure in the transaction manager runtime. If the transaction manager is a 32 bit implementation, then the DB2 related libraries will be available in:

    • For DB2 V8.2: -L$(DB2DIR)/lib
    • For DB2 V9: -L$(DB2DIR)/lib32

    $(DB2DIR)/lib represents the 64 bit versions of the DB2 libraries. You must take care when modifying these files to link in other required libraries.

  4. Build the application

    Tp pre-compile the embedded SQL file:

    db2 connect to ${DB2DBDFT}; \
    db2 prep <samples>.sqc; \
    db2 grant execute on package <package> to <group>; \

    To compile the generated C code:

    $(Compiler) $(CCFLAGS) $(LDFLAGS)

Resource manager: Oracle

  1. Configure the transaction manager

    Here is an example of an XA open string for Oracle:


    This example causes the transaction manager process to connect to the database with these parameters:

    • As user <user> with password <password>, as shown in Acc=P/<user>/<password>.
    • With inactive transactions aborted after 35 seconds (SesTm=35).
    • With log files created in the /tmp directory LogDir=/tmp.
    • With XA procedure calls and returns logged in the log file (DbgFl=1).
  2. Prepare the resource manager

    Key points:

    • The transaction manager should provide the ax_reg and ax_unreg implementations.
    • You need to grant the relevant privileges to the user who is trying to execute the transaction; for example:

      sqlplus> grant select on dba_pending_transactions to <user>

  3. Build the switch-load file

    Oracle provides switch structures for both static and dynamic registration; the switch structure for static registration is called xaosw and the switch structure for dynamic registration is called xaoswd.

    With static registration, the switch-load file will look like:

    struct xa_switch_t * TM_XA_Init(void)
        tm_xa_switch = "&xaosw;

    With dynamic registration, the switch-load file will look like:

    struct xa_switch_t * TM_XA_Init(void)
        tm_xa_switch = "&xaoswd;
  4. Build the application

    The pre-compile step should be similar to this:

    proc $(OPTIONS) iname=<sample>.pc
    Typical options may include 
    OPTIONS=include=/$(TM_INSTALL_PATH)/include auto_connect-yes \
                    release_cursor=yes sqlcheck=syntax ireclen=512

    The compile step should be similar to this:

    LDFLAGS       = -L${ORACLE_HOME}/lib32 -lclntsh
    $(Compile) $(CCFLAGS) $(LDFLAGS)

    You might be required to rebuild libclntsh for the dynamic registration case using the library from the transaction manager, which provides the implementation for ax_reg and ax_unreg functions.

Resource manager: WebSphere MQ (Version 6)

  1. Configure the transaction manager

    An example of a commonly used format for the XA open string for WebSphere MQ is:


    which is the name of the queue manager to connect to.

  2. Prepare the resource manager for XA communication

    When trying to access WebSphere MQ as part of the transaction, you (as the user) should be in the mqm group and have the appropriate MQI authorizations required for the transaction.

  3. Build the switch-load file

    A switch-load file called $MQ_HOME/lib/amqzsc is supplied with WebSphere MQ. A source file called $MQ_HOME/samp/amqzscix.c is also included with MQ to enable you to build your own switch-load file.

    Compile the switch-load file as shown:

    $(COMPILER) $(MQM_ROOT)/samp/amqzscix.c -I($MQM_ROOT)/inc -e 
    amqzscix -bE:tmp.exp -bM:SRE -o amqzscix 
    -L$(MQM_ROOT)/lib -lmqmcics_r -lmqmxa_r -lmqz_r -lmqmcs_r -lmqmzse
  4. Build the application

    There is no pre-compile step for a WebSphere MQ application. The compile step should be similar to this:


Resource manager: Informix

  1. Configure the transaction manager

    The XA open string in Informix typically uses this format:


    which is the name of the database.

  2. Prepare the resource manager for XA communication

    The administrator needs to grant privileges for using the Informix server with the transaction manager, as in this example:

    ESQL>grant resource to <user>

  3. Build the switch-load file

    The switch structure is called infx_xa_switch and the switch-load file needs to be modified accordingly.

    The switch load file will look like:

    struct xa_switch_t * TM_XA_Init(void)
        tm_xa_switch = "& infx_xa_switch;

    To compile the switch-load file:

    $(COMPILER) -v –I$(TM_INSTALL_PATH)/include \
            informix_xa.c \
            -o informxa \
            -eTM_XA_Init \
            -L$(INFORMIXDIR)/lib \
            -L$(INFORMIXDIR)/lib/esql \
            -L$(TM_INSTALL_PATH)/lib \
            -l$(TM_RUNTIME_LIB) \
  4. Build the application

    The pre-compile step should be similar to this:

    esql -e <sample>.ec

    The compile step should be similar to this:

    ${INFORMIXDIR}/lib/libcicsshr.o -lthsql -lthgen -lthos -lifglx -lifgls -lm

Resource manager: Sybase (Versions 12.5 and 15)

  1. Configure the transaction manager

    The XA open string in Sybase typically uses this format:

    -U userName -P password -N LRMname -L logFile [-T traceLevel]


    • userName and passWord identify the connection to the Sybase database. Both must refer to a valid Sybase user account, which is created by the Sybase system administrator.
    • LRMname is the name of the LRM, as defined in the Sybase XA configuration file $SYBASE/xa_config. The LRM name is identified in the XA transaction with the command EXEC SQL SET CONNECTION LRMname.
    • logFile is the full pathname of the file to which tracing information is written. This log file is needed for error messaging.
    • traceLevel is the level of trace written to the log file.
  2. Prepare the resource manager for XA communication

    The administrator needs to edit the xa_config file, grant privileges to the user for use of the Sybase LRM, and configure the server for distributed transaction management.

  3. Build the switch-load file

    A sample make file to build the switch-load file to use in this case could look like:

    SYBLIBS_sybase15 =   -lsybct_r -lsybcs_r -lsybtcl_r -lsybcomn_r -lsybintl_r
    SYBLIBS_sybase12.5 = -lct_r -lcs_r -ltcl_r -lcomn_r -lintl_r
    SYBXALIB_sybase15 = -lsybxadtm
    SYBXALIB_sybase12.5 = -lxadtm
    all: usage
            @echo "Usage: make -f [ sybase12.5 | sybase15 ]"
    sybase12.5 + sybase15: sybasexa.c
            $(COMPILER) ${CFLAGS_$@} \
            -I$(TM_INSTALL_PATH)/include sybasexa.c \
            -o sybasexa \
            -eCICS_XA_Init \
            -L$(TM_INSTALL_PATH)/lib \
            -L${SYBASE}/${SYBASE_OCS}/lib ${SYBXALIB_$@} ${SYBLIBS_$@} 
            $(TM_RUNTIME_LIB) \
            $(TM_REPLACEMENT_SWITCH) \
  4. Build the application

    The key point to note here is the difference between the library names for Versions 12 and 15 of Sybase.

    The pre-compile step should be similar to this:

    cpre <sample>.cpre

    The compile step should be similar to this:

    CCFLAGS='-I${SYBASE}/${SYBASE_OCS}/include -DXA - 
    SYBLIBS_12.5 = -lct_r -lcs_r -ltcl_r -lcomn_r -lintl_r
    SYBLIBS_15 = -lsybct_r -lsybcs_r -lsybtcl_r -lsybcomn_r -lsybintl_r
    SYBXALIB = -lxadtm
    SYBXALIB_15 = -lsybxadtm
    LDFLAGS_12.5= -L${SYBASE}/${SYBASE_OCS}/lib ${SYBXALIB_12.5} 
    ${SYBLIBS_12.5}  ${SYSLIBS}"; \
    ${SYBLIBS_15}  ${SYSLIBS}"; \

    A typical make file could look like <sample_make>.mk:

    all: usage
            @echo "Usage: make -f <sample_make>.mk 
    [ XA_sybase12.5 | XA_sybase15]"

Considerations for application programmers

Application need to be especially cognizant of transaction processing, as there are additional considerations that must be accommodated in an application running in this environment:

  • Behavior of transaction manager if the resource manager fails

    It is important that the transaction manager is able to handle catastrophic failures of the resource managers, and as such continue operating if one of the resource managers has a failure. Application programmers should be sure to test the behavior of the transaction manager in such situations to sufficiently accommodate any necessary special handling.

  • Application structure and restrictions

    Some transaction managers configured for XA communication restrict application programmers from using resource manager-specific two-phase commit statements. For example, when writing an embedded SQL application for DB2 to work in an XA environment, the application should not have an EXEC SQL COMMIT statement, since the two-phase commit procedure is handled by the transaction manager itself.

  • Commit: Single phase optimization vs. two-phase

    Some configurations, such as those with only one database resource, do not require the full data integrity that is provided by the two-phase commit protocol of the XA interface. A single-phase commit optimization enables higher performance in which data integrity is not such an issue. If a database failure occurs, the transaction manager reports the possibility of inconsistent data from failed transactions. However, administrators need to check the consistency of the data if multiple resource managers are involved in the failing transactions. If the database is the only resource manager that is participating in the transactions, the data is consistent.

  • Error handling

    Application programmers should make sure to handle the API errors returned by the resource managers, because it is possible that some of these errors are not handled by the transaction manager. Transaction managers typically handle XA protocol-related errors.

  • Read-only optimization

    A resource manager is a read-only participant in a transaction if it need not make any changes to its local data on behalf of the transaction. To a read-only participant, it makes no difference whether a transaction commits or aborts. The resource manager does not perform any logging and does not participate in the second phase of the two-phase commit. In the event that all the transactions are read-only, the entire second phase is avoided. This helps in the overall performance improvement.


This article presented some general concepts on XA processing and highlighted some specific considerations that go into using several popular middleware resource managers with a transaction manager in an XA environement.



developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into WebSphere on developerWorks

Zone=WebSphere, Information Management
ArticleTitle=IBM WebSphere Developer Technical Journal: Configuring and using XA in a middleware environment