The resource manager declares itself by contacting the local transaction manager, then waits for execution requests from an application program. When a request arrives with a new transaction object, the resource manager enlists in the transaction by invoking the Enlist method on the transaction object. By enlisting, the resource manager ensures that it will get callbacks from the transaction manager when the transaction commits or aborts. The resource manager then performs the transaction's requests.
For example, the transaction might insert, delete, or update records in a relational database. The resource manager retains enough information to enable it to either undo or redo the transaction, such as by storing multiple versions of the data or keeping a log (journal) of the changes.
When the application program commits the transaction, the transaction manager initiates the two-phase commit protocol. The transaction manager first queries each enlisted resource manager if it is prepared to commit the transaction. The resource manager must then prepare to commit by preparing to either commit or abort the transaction. Typically, the old and new data is recorded in stable storage so that the resource manager can recover it even if the system fails. If the resource manager can’t prepare successfully, it informs the transaction manager that it can’t prepare and the transaction manager aborts the transaction. If the resource manager can prepare, it informs the transaction manager that it is prepared, and awaits the transaction manager's decision on whether to commit or abort the transaction.
Once prepared, a resource manager must wait until it gets a commit request or abort request from the transaction manager. Most transactions commit; a few transactions abort. The entire prepare and commit protocol typically completes within a fraction of a second, however, a system or communication failure may delay the commit or abort notification for several minutes or even hours. During this period, the resource manager is in-doubt about the outcome of the transaction; it doesn't know whether the transaction committed or aborted. While the resource manager is in-doubt about the transaction, it locks the data modified by the transaction, isolating these changes from any other transactions.
The previous example discusses how distributed transactions are made atomic in a fault-free environment. See Participating in the Two-Phase Commit Protocol for a more detailed example.
MS DTC also helps resource managers make transactions atomic and durable when a resource manager fails and then restarts. The resource manager must reconstruct the committed state of the resources it manages, reflecting all of the effects of committed transactions and none of the effects of aborted transactions.
When a resource manager fails, all of its enlisted transactions are aborted, except those which prepared or committed prior to the failure. When the resource manager restarts, it queries the transaction manager about the outcome of the in-doubt transactions in which it enlisted. The transaction manager tells the resource manager the outcome of each in-doubt transaction and the resource manager commits or aborts these transactions accordingly.
The two-phase commit protocol, combined with prepare and recovery routines of the resource managers, make transactions atomic and durable.