MTS evolved as a Transaction Processing (TP) system to provide on Windows NT the same kinds of features as available in CICS®, Tuxedo®, etc. on other platforms. These are purely designed for creating stable transactional environments for data sources—predominantly relational databases like IBM's DB/2, Oracle, Informix and Sybase. Microsoft Transaction Server already offers support for SQL Server and Oracle, and will be extended to cover the other mainline database systems in the future.
Distributed Transactions
The first thing to consider is why we might want to extend transactions to MTS, instead of using the traditional database-implemented transactions we discussed earlier. The most obvious is that transactions within a database system can only encompass that database, although they can—of course—span different tables within it.
In the real world, we often need to carry out transacted operations that span different databases, which may be on different servers and even at different sites. Think back to the Wrox Car Co application where, as you saw earlier, we need to update both a local database on the showroom server and a remote database at the head office. Both updates must fall within the same transaction to make any sense. MTS can do this for us (almost) automatically.
Resource Managers and the DTC
When MTS (or SQL Server) is installed, a separate service is added to Windows NT called the Distributed Transaction Coordinator (DTC). This runs as a service under Windows NT, and is used to coordinate transactions that span separate data stores or resources. To work, it requires each data store to implement its own proprietary Resource Manager (RM). SQL Server and most major databases already include these, though at present not all are compatible with the Windows NT DTC. They are generally part of the driver software—perhaps OLE-DB but more often ODBC at the moment.
The common protocol for communication between the DTC and the resource managers is XA, developed by the X/Open group. MTS supports this, and also its own protocol called OLE Transactions (currently only available for SQL Server). Notice, however, that we talk about 'data stores' rather than databases—one of the aims of Microsoft's Universal Data Access initiative is to provide seamless access to all kinds of data. OLE-DB drivers are becoming available for of Microsoft's own applications, such as the Active Directory Service and Exchange message stores.
To understand how a distributed transaction works, look at the following diagram. When a component requests access to a data store, the data store driver (usually OLE-DB or ODBC) checks with the appropriate MTS context object to see if a transaction is required. If it is it informs the DTC, and then contacts the resource manager for the data store and tells it to start a transaction within that data store—in other words it automatically starts an integral 'database' transaction for this operation. Then the component (in this case via ADO) can work with the data on this device through the driver software; adding, updating and deleting records as required:
In the simplest case, where the component only accesses this data store and no other, it can call the
(or SetComplete
) method once all the actions on the data are complete. This tells the DTC that the transaction is complete, and (under XA protocol) it instructs the driver software to commit or abort the transaction as appropriate. If the system is using OLE Transactions, the DTC can communicate directly with the resource manager to commit or abort the transaction instead of getting the driver to do it.SetAbort
Now consider the case where we have two data stores to update within one transaction. In this case, the DTC and driver software start the database transaction in the first data store via the resource manager, as before. Then, once the component opens a connection to the second data store, the DTC and driver software contact this resource manager and tell it to start a new internal transaction for the updates that follow. Now both data stores are holding open transactions with the updates:
Once the component calls the
or SetComplete
method the DTC contacts (via the driver software if XA is being used) both resource managers and instructs them to commit or abort their current transaction. In this way, the transaction within MTS has been expanded to include the remote data stores as well. Either all the updates on all the data stores will succeed, or all will be rolled back.SetAbort
Controlling MTS Transactions Explicitly
The context object that is created when a client application references a component in MTS provides information to MTS, the client, and other software such as the data source driver and the DTC. This information includes the 'transaction' setting for the component, which depends both on the properties set when it was installed in MTS and the code in the application—such as an ASP page that uses the component.
As well as calling the
and SetComplete
methods, a component can exert control over how transactions work. For example it can call the SetAbort
method to prevent the DTC allowing a DisableCommit
or SetComplete
method to commit open data store transactions on all resource managers until further notice. When it’s ready to commit or abort the transaction, it can call the SetAbort
method.EnableCommit
Creating Objects Within Transactions
Often, as it executes, a component needs to create instances of other objects with which to work. For example, an order handling component may need to create instances of a 'customer' object to get information about the customer that is placing the order. In VB, there are two main ways to create an instance of another object,
and New
. MTS adds another method, CreateObject
. We’ll look at the differences in the next section, where we examine all the methods that MTS provides in more detail.CreateInstance