Implementing DTC Interfaces
Updated: July 19, 2016
Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista
IResourceManagerSink is required for building a relationship between the resource manager and the transaction coordinator.
ITransactionResourceAsync is required for receiving the two-phase notifications for a transaction in which the resource manager is enlisted. There is one instance of ITransactionResourceAsync per enlistment. Typically, there is one enlistment per transaction, but a resource manager can choose to enlist multiple times in the same transaction.
A resource manager generally follows these steps:
The resource manager calls the DtcGetTransactionManager function to get a reference to the IUnknown interface on the DTC proxy core object. Using this reference, the resource manager can call QueryInterface for IResourceManagerFactory and then calls IResourceManagerFactory::Create for a reference to the resource manager object'sIResourceManager interface, which the resource manager uses to enlist in new transactions and to perform recovery.
After it establishes a relationship with the DTC, the resource manager can obtain a transaction's ITransaction interface and enlist in this transaction by invoking IResourceManager::Enlist. One of this method's parameters is an instance of ITransactionResourceAsync.
When the initiator of the transaction invokes ITransaction::Commit, the DTC initiates the voting phase of the two-phase commit protocol. The first phase notification is delivered to the enlisted resource manager by invoking ITransactionResourceAsync::PrepareRequest. The resource manager then performs the relevant work to move from an active state to a prepared state and, on moving to the prepared state, invokes ITransactionEnlistmentAsync::PrepareRequestDone.
The decision phase notification is provided to each enlisted participant by the invocation of ITransactionResourceAsync::CommitRequest. A resource manager responds to this notification by invoking ITransactionEnlistmentAsync::CommitRequestDone.
The Abort notification works the same way as the first phase notification but with no second phase.
Application code (such as a stored procedure) may exist in-process with a resource manager. This application code could obtain a DTC transaction, and because it is in-process with the resource manager, it could provide a reference to the ITransaction interface on the transaction object to the resource manager, which then can enlist in that transaction.
The recovery process consists of the following two steps:
The resource manager examines the log file to identify all the prepare information records for transactions that are in-doubt. For each such transaction, it invokes IResourceManager::Reenlist, which provides the outcome for that transaction. If the DTC doesn't know the transaction outcome, Reenlist fails with an XACT_E_REENLISTTIMEOUT error message, in which case the resource manager will need to retry at a later time.
The resource manager invokes IResourceManager::ReenlistmentComplete when the resource manager learns the outcome for all the in-doubt transactions. This method completes the recovery and informs the DTC that the resource manager has no more in-doubt transactions. By invoking, the resource manager guarantees that it will not invoke the Reenlist method again.
A resource manager to is not required to resolve all in-doubt transactions before enlisting in new transactions. Step 1 can be performed at any time after the resource manager establishes a relationship with the DTC, but after ReenlistmentComplete has been invoked (step 2), step 1 cannot be performed again. Step 2 can be repeated multiple times without affecting the outcome of transactions.