|
HP OpenVMS systems documentation |
Previous | Contents | Index |
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:
DECdtm supports the following methods of binding:
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:
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 HP 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:
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 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). HP 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
HP 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:
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:
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, HP 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:
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:
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. |
By default, the XA Veneer calls xa_recover in any process that has bound an RM instance. This is undesirable if the process called to perform recovery runs at low priority or executes an application that may be blocked for link periods with an active transaction. It is especially undesirable if the process uses a resource manager such as Oracle that waits during an active transaction if it finds data that needs recovery.
It is therefore preferable to create one or more processes that are available to perform recovery but which do not execute transactions. You can do this in the following way:
The executable code of the process is provided by the module SYS$LIBRARY:DDTM$XA_RECOVERY.OBJ. Alternatively, you can create a custom process using the following code as a starting point:
#define DESC_INIT_S(p1, p2, p3) \ (p1).dsc$w_length = p2, \ (p1).dsc$b_dtype = DSC$K_DTYPE_T, \ (p1).dsc$b_class = DSC$K_CLASS_S, \ (p1).dsc$a_pointer = (char *) (p3) main() { int status; struct dsc$descriptor dscName; struct dsc$descriptor dscValue; /* enable recovery in this process */ DESC_INIT_S(dscName, strlen("SYS$DECDTM_XA_RECOVER"), "SYS$DECDTM_XA_RECOVER"); DESC_INIT_S(dscValue, 1, "T"); status = lib$set_logical(&dscName, &dscValue); if ((status & 1) != 1) { printf("Failed to define logical name, status %d\n", status); exit(EXIT_FAILURE); } /* open XA RMs */ status = ax_open_decdtm(); if (status != TX_OK) { printf("Error %d on ax_open_decdtm\n", status); exit(EXIT_FAILURE); } /* wait for recovery requests */ while (1) sys$hiber(); } |
To link the process, include the following object modules and libraries:
To restore the default behavior (process joins active transactions and
may perform recovery) when SYS$DECDTM_XA_RECOVER has been defined as a
group or systemwide logical, define SYS$DECDTM_XA_RECOVER as 0 (zero)
for the process.
30.7.1.6 Error Logging
The DECdtm XA log file records heuristic decisions and other serious errors that may impact transaction consistency. Typically, these occur on xa_commit() or xa_rollback(), or during recovery. Less serious errors, such as on xa_prepare, are not logged.
To enable logging, define the logical name SYS$DECDTM_XA_LOG to specify a log file. You can define the logical name processwide, groupwide or systemwide. The log file is created automatically and is shared between processes.
Each record on the log file has the following format:
tid, bid, time, error_name, rm_name, [reserved], additional_information |
Error names are fixed-length 8-character strings with space padding as shown in Table 30-3.
Error Name | Meaning |
---|---|
GETDTI | DECdtm was unable to resolve the transaction state. |
HEURCOM | The transaction branch has been heuristically committed. |
HEURHAZ | The transaction branch may have been heuristically completed. |
HEURMIX | The transaction branch has been heuristically committed and rolled back. |
HEURRB | The transaction branch has been heuristically rolled back. |
INVAL | Invalid arguments were specified to xa_open. Probably the rm_info string is incorrect. |
RMERR | Catastrophic RM failure on xa_commit(). |
RMFAIL | An error occurred that makes the resource manager unavailable. |
UNKNOWN | Unexpected return code from the RM. |
The XA Veneer includes a trace facility to help investigate problems of interaction between DECdtm and XA resource managers. The trace file shows the sequence of operations. It also shows more detailed error information than that revealed by XA return values.
To enable tracing, define the logical name SYS$DECDTM_XA_TRACE to specify a trace file. You can define the logical name processwide, groupwide or systemwide. The trace file is created automatically and is shared between processes.
The trace file records the following information:
Trace records have the following formats:
Record Type | Format |
---|---|
Operation | time csid pid operation [rmid] |
Status | time csid pid xa_status ["VMS" vms_status] [extra_info] |
Previous | Next | Contents | Index |