How a Resource Manager Can Get XA Compliance Using MS DTC

There are many new resource managers (RMs) being written which implement the OLE Transactions protocol in order to participate in distributed transactions. Some of these RMs would also like to be XA-compliant, meaning that transaction managers that use the XA protocol can coordinate them. Microsoft Distributed Transaction Coordinator (MS DTC) provides a mechanism that allows RMs to get XA compliance without having to implement the XA protocol. MS DTC exports a function that makes the resource manager XA-compliant. In actuality, it translates from XA to the OLE Transactions protocol, thereby allowing all OLE Transactions RMs to participate in XA transactions.

MS DTC provides all the functionality for RMs to be a fully XA-compliant. It implements the XA_Switch and makes it available through a static library. It also exposes an interface called IXATransLookup that an RM or an RM proxy can use to obtain an ITransaction for an XA transaction.

How MS DTC Communicates with the XA TM

The following steps occur when MS DTC communicates with the XA TM:

  1. The application provides information to the XA TM about all the resource managers that it will use. The application then begins a new transaction on the XA TM. This transaction is begun on a thread referred to hereafter as a Windows NT thread.

  2. At the time a new transaction is begun, the XA TM will use the information provided by the application to inform each RM about the transaction. It does by calling xa_start, an XA function. The RM in this case will be MS DTC from the XA TM's perspective.

  3. When xa_start is called, MS DTC creates an entry in its association table which specifies what thread (a thread here means an Windows NT thread) is on which transaction. The association table contains tuples of the form <Thread_Id, XID, pITransaction>. The first element is the thread identifier, the second parameter is the XID that was passed in as an argument to xa_start by the XA TM, and the third element is an OLE Transactions transaction that was created by MS DTC in correspondence with the XID.

  4. Steps 2 and 3 were executed on the thread with which the application notified the TM to begin a transaction. Having begun a transaction, the thread returns to the application. Now the application needs to inform the RM about the new transaction.

    How it does that is RM-specific. As an example, Microsoft SQL Server provides a new DB-Library function in its RM proxy :

    int dbEnlistInXaTrans ( dbProc, ...)

    dbProc is the parameter which indicates which DB-Library connection is being requested to participate in the distributed transaction. Knowing that this is an XA transaction, DB-Library (which is the RM Proxy for MS SQL Server) needs to obtain the ITransaction that corresponds to the XA transaction which the application is requesting it to enlist the connection on. At that time DB-Library does the following:

    • Obtains the IXATransLookup interface from MS DTC

    • Invokes the Lookup method on this interface, and gets back the ITransaction that it needs.

    • It then does what it would normally do to enlist a connection in a OLE Transactions transaction.

It was mentioned previously that MS DTC creates an entry in an association table when it is notified of a new XA transaction. It obtains the thread ID of the thread by calling the IXATransLookup::Lookup method and looks for an entry in the association table using the thread ID as the key. Once it finds the entry, it returns a reference to the corresponding ITransaction to DB-Library, which had called the IXATransLookup::Lookup method.

At the end of the task, the application calls Commit or Abort, which goes to the XA TM. The XA TM then sends the two-phase commit messages to the RMs, including MS DTC. MS DTC receives the messages and sends the corresponding two-phase commit messages to the OLE Transactions RMs that are enlisted with it.

Interface IXATransLookup

This interface has only one method. This interface can be obtained by calling QueryInterface on other MS DTC interfaces or by the calling the function DtcGetTransactionManager.

interface IXATransLookup : IUnknown

{ HRESULT Lookup( [out] ITransaction ** ppTransaction); };

IXaTransLookup::Lookup

The resource manager or the resource manager proxy calls this method to get a pointer to the ITransaction interface which the calling thread is on.

HRESULT Lookup (

ITransaction ** ppTransaction);

Parameters

ppTransaction [out] The ITransaction interface which the calling thread is on.

Return Codes

S_OK Success.

XACT_E_NOTRANSACTION

The calling thread is not associated with any transaction.

E_INVALIDARG

One or more of the parameters are not valid.

XACT_E_ABORTED

The transaction which the thread was on has aborted, possibly due to timeout or unilateral abort.