HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

30.6 Communication Resource Manager Interface

A Communication Resource Manager (CRM) is a special resource manager that acts as a gateway between DECdtm and another TM. Typically, the other TM would be on a system other than an OpenVMS system. You can also write a CRM to link two DECdtm systems using an otherwise unsupported communication mechanism such TCP/IP.

A CRM in a subordinate branch of a DECdtm transaction is indistinguishable from a normal RM. It responds to DECdtm events normally, except that internally it forwards the events to the remote TM instead of dealing with them directly.

A CRM may create a DECdtm subordinate branch using the $JOIN_RM service as follows:

  • Sets the DDTM$M_COORDINATOR flag to indicate that it is a coordinator on behalf of another TM.
  • Specifies a new TID. No call to $START_TRANS is required.
  • Calls $START_BRANCH with the branch ID returned by $JOIN_RM. Specify the CRM instance node as the transaction manager node name (tm_name). No call to $ADD_BRANCH is required.
  • Uses the $TRANS_EVENT service to prepare, commit, or abort a transaction.

The new TID is derived from the remote TM and must be a universal unique identifier (UUID). If the remote TM does not use UUIDs for its TIDs, the CRM must generate a new TID (using the $CREATE_UID service) and maintain a mapping between remote TM TIDs and DECdtm TIDs. If multiple branches of the same transaction are created, you must use the same DECdtm TID on all branches. Otherwise, RMs may detect spurious lock collisions between branches of the same transaction.

30.7 DECdtm XA Interface (Alpha Only)

The DECdtm XA interface allows a transaction manager (TM) to coordinate transactions performed by a resource manager (RM). For an overview and documentation of the XA interface, see the X/Open CAE Specification document Distributed Transaction Processing: The XA Specification.

The DECdtm XA interface provides the following levels of support for the XA interface:

  • The DECdtm XA Veneer allows an XA-compliant RM (such as Oracle) to participate in a global transaction coordinated by DECdtm. As Figure 30-2 shows, you typically use this to combine the XA-compliant RM in a transaction with DECdtm-compliant RMs, such as ACMS, Oracle Rdb, and RMS Journaling.
    The XA Veneer is a per-process set of functions that call DECdtm system services on behalf of the RM and map DECdtm events to XA function calls.
  • The DECdtm XA Gateway allows you to coordinate a DECdtm-compliant RM (such as Oracle Rdb or RMS Journaling) using an XA-compliant transaction processing system, such as BEA TUXEDO. (See Figure 30-3.)
    The XA Gateway is an XA RM that DECdtm uses to participate in an XA transaction as a subordinate TM. DECdtm passes transaction events to the DECdtm-compliant RMs.

Figure 30-2 XA Veneer Example


Figure 30-3 XA Gateway Example


Figure 30-4 TX Wrapper Example


For the convenience of application writers, the DECdtm XA Interface also provides an implementation of the X/Open TX (Transaction Demarcation) interface. This is a simple set of function wrappers for DECdtm system services. (See Figure 30-4.)

The following sections describe the DECdtm XA interface:

30.7.1 Using the XA Veneer

This section describes how to write an application program that uses an XA-compliant RM in transactions coordinated by DECdtm.

30.7.1.1 Transaction Demarcation

Application programs can use the $START_TRANS, $END_TRANS, and $ABORT_TRANS system services to control transactions.

XA RMs can participate only in the default transaction, because the XA interface model does not allow for explicit transaction IDs passed to RMs by APs.

DECdtm does not support DECthreads or POSIX threads. That is, you can use threading within an application, but the default transaction is managed per process, not per thread.

The XA Veneer does not support the use of $SET_DEFAULT_TRANS to change the current default transaction. That is, an application program may attempt to change the current default transaction, but XA RMs will continue to perform operations in the context of the original default transaction.

The Veneer reports RM xa_start() errors on $START_TRANS by an SS$_ABORT exception. Any RM error also causes the transaction to be aborted and a reason code to be returned from $END_TRANS.

RM return codes are translated to reason codes as follows:

XA Return Code DECdtm Reason Code
XA_RBCOMMFAIL DDTM$_COMM_FAIL
XA_RBDEADLOCK DDTM$_PART_SERIAL
XA_RBINTEGRITY DDTM$_INTEGRITY
XA_RBTIMEOUT DDTM$_PART_TIMEOUT
Other XA_RB* DDTM$_VETOED
XAER_DUPID Veneer fails
XAER_INVAL Veneer fails
XAER_NOTA DDTM$_UNKNOWN
XAER_PROTO Veneer fails
XAER_RMFAIL DDTM$_SEG_FAIL
All others DDTM$_UNKNOWN

The XA Veneer implements the functions ax_open_decdtm() and ax_close_decdtm(). They are identical to the X/Open TX functions tx_open() and tx_close. If ax_open_decdtm() is not called, XA RMs are automatically opened at the start of the first transaction.

Application programs can use the X/Open TX functions instead of DECdtm system services. The TX functions are available in an object module that can be used with the XA Veneer. The tx_begin() function includes an exception handler that maps XA Veneer exceptions to tx_begin() return codes. While the TX wrapper module requires the XA Veneer, the TX functions apply equally to XA and DECdtm RMs.

30.7.1.2 Locking Between Processes

A transaction may access an RM from more than one process. The XA Veneer creates a separate branch of the transaction for each process. This requests the RM to treat each process as a loosely coupled thread as defined by the XA specification. The RM takes locks to isolate access to a resource in one process from access in another process. Consequently, the processes may deadlock against each other if they attempt to access the same resource within a single transaction.

30.7.1.3 Binding to the XA Interface

Before a resource manager can take part in transaction processing, it must be bound to the XA interface. The XA interface requires the following:

  • The address of the XA Switch data structure for the resource manager. See the resource manager documentation for the symbolic name of this switch.
  • The xa_info text strings for xa_open() and xa_close(). See the resource manager documentation for the specification of these strings.
  • An optional name for the resource manager instance. (See Section 30.7.1.3.3.) The maximum length of the name is 24 characters, excluding the null terminator.

DECdtm supports the following methods of binding:

  • Static binding is the method implied by the XA standard. The address of the XA Switch and the xa_info text strings are determined at link time.
  • Dynamic binding requires a run-time call to a nonstandard function. This method gives the application control over the time at which binding and recovery is performed.

You can find definitions of the data structures and constants required to use the XA interface in SYS$LIBRARY:XA.H. This is the "xa.h" as listed in the XA specification. Additional nonstandard functions and flags are defined in SYS$LIBRARY:DDTM_XA.H.

To use an XA compliant RM, you must link the application with the following:

  • The RM's shareable image or object files.
  • SYS$LIBRARY:DDTM$XA_RM.OBJ. This object module contains a table of well-known resource managers and initialization code to load the XA Veneer.
  • SYS$LIBRARY:DDTM$XA.EXE. This shareable image implements the XA Veneer.

You can also link an application against SYS$LIBRARY:DDTM$TX.OBJ to use the TX transaction demarcation interface instead of DECdtm system service calls.

You must install the privileged shareable image SYS$LIBRARY:DDTM$XA_SS.EXE. It provides system services for internal use by the XA interface.

30.7.1.3.1 Static Binding

You bind resource managers by creating and linking a small object module. The object module places references to the XA Switch and xa_info string in the predefined PSECT DDTM$AX_RM. Consider the following Compaq C sample:


  /* TODO: define or reference your RM switch */
    extern struct xa_switch_t   SampleSwitch;

    /* TODO: define the info strings for xa_open() and xa_close() */
    static char RmInfoOpen[] = "SampleInfoOpen";
    static char RmInfoClose[] = "SampleInfoClose";

    /* TODO: define the RM instance name */
    static char RmName[] = "SampleName";

    /* put the switch and info addresses in the DDTM$AX_RM psect */
    #pragma extern_model strict_refdef "DDTM$AX_RM" pic, shr

    void* RmDefSample[] = {&RmSwitchSample,
                           RmInfoOpen, RmInfoClose, RmName};

To bind the resource manager, make the following changes to the sample file:

  1. Change "SampleSwitch" to the symbolic name of the XA switch structure as given in the documentation for your RM.
  2. Change "SampleInfoOpen" and "SampleInfoClose" to xa_info strings as given in the documentation for your RM. Typically, the xa_open string will specify a database name and access information, and the xa_close string may be null.
  3. Change "SampleName" to a resource manager instance name that you choose, as described in Section 30.7.1.3.3.

If you prefer to code the RM definition in another language, such as VAX MACRO, note the full attributes of the PSECT as follows:


    .PSECT DDTM$AX_RM,CON,GBL,SHR,NOEXE,WRT,NOCOM,4

To make the xa_info strings configurable, the XA Veneer attempts to translate the strings in the SYS$DECDTM_XA_RM logical name table. If the strings cannot be translated, they are passed unchanged to the resource manager.

When you use static binding, the XA Veneer calls xa_recover() either when tx_open() is called or at the start of the first transaction in the image lifetime.

You can use ax_close_decdtm() to close statically bound resource managers.

30.7.1.3.2 Dynamic Binding

An application program can bind additional RMs to the XA Veneer by calling ax_bind_decdtm_2(). Dynamic binding requests the XA Veneer to call xa_recover(), which allows recovery to be initiated earlier than with static binding.

Note that ax_open_decdtm() and ax_close_decdtm() have no effect on dynamically bound resource managers.

30.7.1.3.3 Resource Manager Instances

You must specify the resource manager instance name if the resource manager implements multiple instances (or databases) that may be recovered independently. You cannot bind a resource manager into a single process multiple times, unless each binding is for a different named instance.

You must also specify a resource manager instance name if the resource manager instance name in the XA Switch structure is longer than 24 characters. Otherwise, if the resource manager does not support multiple instances, the instance name may be set null, and DECdtm uses the resource manager name in the XA Switch structure as the instance name.

The definition of resource manager instances controls the following features of the XA Veneer:

  • When DECdtm calls xa_recover(), it expects that the resource manager instance returns the complete list of prepared transaction branches for the instance. DECdtm will forget any transactions for the instance that are not returned by xa_recover().
  • If a process or OpenVMS Cluster node using the XA Veneer fails, DECdtm initiates recovery in any one of the surviving processes in the cluster that are bound to the resource manager instance.

When you choose the instance name, you must set it identically in all processes. It has a maximum size of 24 characters (excluding the null terminator). Compaq recommends that the first part of the name is the same as the resource manager name in the XA Switch structure, provided that this is possible within the overall limit of 24 characters.

You can bind a maximum of 1024 resource manager instances in a process.

In this manual, the term "resource manager instance" is used in the same sense as "Oracle Instance" in the Oracle documentation. In the OpenVMS System Services Reference Manual, the DECdtm services descriptions use the same term in a different context and with a different meaning.

30.7.1.3.4 Hints

You may find the following hints to be of help:

  • Check any OpenVMS documentation for your resource manager as well as the generic documentation. For example, the generic documentation for Oracle suggests that you may need to specify an explicit shared library for the Oracle XA RM. However, on OpenVMS no specific action is needed; a reference to the Oracle XA switch structure is sufficient.
  • To use XA transactions with Oracle 8i on OpenVMS, you must install the Oracle DDBOPT product (Distributed Database Option), and you must enable the Distributed Database Option in the configuration options for the Oracle RDBMS product.

30.7.1.4 Implementation Characteristics

This section provides information for developers of XA-compliant RMs that are to be used with the DECdtm XA Veneer.

The DECdtm XA Veneer does not use some features of the XA interface that must normally be provided by resource managers. This information is provided for the convenience of RM developers, to help them decide if an existing implementation is likely to work with DECdtm. Future implementations of DECdtm XA may make use of these features.

This section also describes possible deviations from the XA standard or common interpretations of the standard.

30.7.1.4.1 Threads

DECdtm does not support DECthreads or POSIX p-threads. That is, the default transaction is managed per process, not per thread. When reading the XA specification, you must regard a thread as equivalent to a process.

The Veneer assumes there is a single default transaction per process and does not attempt to suspend or migrate the association of a transaction branch with a thread or process. Thus, it never sets the TMSUSPEND or TMMIGRATE flags on a call to xa_end(), and never sets TMRESUME on a call to xa_start().

The Veneer never sets the TMJOIN flag on a call to xa_start().

30.7.1.4.2 Heuristic Decision

DECdtm does not support heuristic decisions. If the RM reports a heuristic decision on xa_commit() or xa_rollback(), the Veneer records the decision in a log file. The xa_forget() function is called immediately and the transaction is treated as if it committed or aborted normally.

30.7.1.4.3 Resource Manager Synchronization

The XA Veneer always calls XA functions at non-AST level in user mode. The Veneer never interrupts an XA call with another XA call.

The Veneer may interrupt application processing to call the following functions:

  • xa_recover()
  • xa_commit() or xa_rollback() for a transaction listed by xa_recover()

However, such calls are not made while the process has an active transaction, that is, between xa_start() and xa_end(). Therefore, they cannot interrupt the RM while it is executing a call from the application.

TP frameworks, implemented using the earliest version of the DECdtm interface, may run application code in concurrent DECdtm unsynchronized branches. This is not recommended (see the OpenVMS DECdtm Services Reference Manual), partly because the Veneer cannot determine when branch processing ends, and may therefore make xa_end() and xa_rollback() calls asynchronously while an XA RM is processing a call from the application. This occurs only when a transaction is aborted by another DECdtm branch. This problem does not occur with ACMS, because ACMS executes branches serially, not concurrently.

If the version of the TP framework in use does not make a clear statement that synchronized branches are used, and transactions have multiple branches, Compaq recommends that applications protect XA RM calls against asynchronous events using the nonstandard functions ax_lock_decdtm() and ax_unlock_decdtm(). The Veneer may be locked at the start of branch processing and unlocked at the end, or individual RM calls may be protected by paired lock/unlock calls.

30.7.1.4.4 Asynchronous Operation

This implementation does not use asynchronous operations.

The RM Switch flag TMUSEASYNC is ignored. The TMASYNC flag is never set on calls to the resource manager. The xa_complete() function is never called.

30.7.1.4.5 Resource Manager Switch

An RM can ensure that a future version of the Veneer preserves restrictions and possible nonstandard behavior by setting the nonstandard flag TM_DDTM_V1 in the flags field of the XA Switch data structure.

30.7.1.4.6 Image Termination and Recovery

No XA functions are called directly when an image or process terminates.

The RM is dissociated from any active transaction, and the transaction is aborted.

After an image terminates, a process terminates, or a cluster node fails, DECdtm calls xa_recover() on any one of the surviving processes in the cluster that is bound to the same resource manager instance.

30.7.1.4.7 Transaction Branch Identification

In this implementation, formatID is set to 223585243, gtrid_length is 16 and bqual_length is 36. However, RMs should not make assumptions about the values of these fields.

30.7.1.4.8 Error Handling

In most cases, the return values XAER_INVAL and XAER_PROTO are treated as failures of the XA Veneer. An SS$_BUGCHECK exception is reported. See xa_close() and xa_open() in Section 30.7.1.4.9 for exceptions.

In most cases, XAER_RMERR and XAER_RMFAIL have a common interpretation by the Veneer. The current transaction is aborted, but the RM continues to participate in new transactions. The error return values differ only in that they cause different DECdtm reason codes to be returned to the application. See xa_commit() below for an exception.

30.7.1.4.9 XA Functions

ax_reg() A return value of TMER_INVAL indicates that either arguments are invalid or the TMREGISTER flag in the resource manager's xa_switch_t data structure was not set.

A successful call that returns a NULLXID blocks the AP from starting a new default transaction. Other RMs that register through the same thread also receive a success status with a NULLXID.

A call to ax_reg() made while registered fails with XAER_PROTO. TM_JOIN is never returned.

A return value of TMER_PROTO may also indicate that xa_reg() was called while there was a current transaction, but called too late to join it.

ax_unreg() There is no additional information for this function.
xa_close() This function is called for the following reasons:
  • For all statically bound resource managers, when ax_close_decdtm() is called.
  • For a dynamically bound resource manager, when ax_unbind_decdtm() is called.
  • In unusual error cases, typically after an unexpected status is returned by the RM.

This function is not called on image exit or process exit.

The return value XAER_INVAL is assumed to be an invalid rm_info string, not a Veneer failure.

xa_commit() DECdtm does not use the TMNOWAIT flag.

The return value XAER_RMERR is treated as a catastrophic failure of the resource manager. The error is logged and the Veneer fails with a SS$_BUGCHECK exception to prevent further processing.

The return value XAER_RMFAIL is treated as a less severe error. The error is logged. It is assumed that the resource manager will continue to fail all new transactions with XAER_RMFAIL, but that it may eventually be possible to commit the transaction on recovery.

The Veneer attempts to retry xa_commit() when XAER_RETRY is returned. It retries the operation at 10-second intervals for up to 2 minutes.

xa_complete() The Veneer never calls this function.
xa_end() DECdtm does not use the TMSUSPEND or TMMIGRATE flags.
xa_forget() DECdtm does not support heuristic decisions. It calls xa_forget() immediately after an RM reports a heuristic decision.

Error return values are recorded in the Veneer error log, but are otherwise ignored.

xa_open() Any error return leaves the RM unregistered. The error is recorded in the Veneer error log.

The return value XAER_INVAL is assumed to be an invalid rm_info string, not a Veneer failure.

xa_prepare() There is no additional information for this function.
xa_recover() DECdtm calls xa_recover() for the following reasons:
  • When it receives an ax_bind_decdtm_2() call with the DDTM_M_RECOVER flag set.
  • At the start of the first transaction in the image lifetime, if the resource manager is statically bound to DECdtm.
  • When an image that has performed a transaction using XA Veneer terminates, and other processes are still using the XA Veneer.
  • When the resource manager returns from an xa_recover() call with a value equal to count.

DECdtm never sets TMENDRSCAN. Thus, it always performs full scans for prepared transaction branches.

DECdtm expects that the RM returns the complete list of prepared transactions started on the current node of the OpenVMS Cluster for an RM instance. Any other transactions that the RM has forgotten will be forgotten by DECdtm. The RM may also return prepared transactions started on other nodes, and these will be resolved.

xa_rollback() There is no additional information for this function.
xa_start() DECdtm does not use the TMNOWAIT flag.

DECdtm does not use the TMJOIN or TMRESUME flags.

The return value XAER_DUPID is not expected, because DECdtm calls each resource manager once only for each transaction. It causes the Veneer to report an SS$_BUGCHECK exception.

The current DECdtm implementation is unable to return an error from $START_TRANS when the RM returns an error. Instead, the Veneer raises an SS$_ABORT exception, which the application may dismiss. The application should call $END_TRANS or $ABORT_TRANS. The transaction will be aborted in either case. $END_TRANS returns.


Previous Next Contents Index