Click Here to Install Silverlight*
United StatesChange|All Microsoft Sites
MSDN
|Developer Centers|Library|Downloads|Code Center|Subscriptions|MSDN Worldwide
Search for


Advanced Search
MSDN Home > MSJ > August 1997
August 1997


Microsoft Transaction Server Helps You Write Scalable, Distributed Internet Apps

Dave Reed, Tracey Trewin, Mai-lan Tomsen

Because MTS uses a component-based application development model with a transaction processing runtime infrastructure, you can break down your business logic into ActiveX components—using your favorite development tool—that can be updated and managed easily.

This article assumes you're familiar with COM and Visual Basic

Code for this article: Mts.exe (305KB)
Dave Reed (product unit manager), Tracy Trewin (program manager), and Mai-lan Tomsen (programming writer) are part of the MTS product team at Microsoft.

Talk to anyone building a multiuser enterprise server application and they will tell you about all sorts of interesting problems they solved that had nothing to do with the actual business logic. Complex problems relating to thread management, security authorization, and transaction support across multiple databases might come up. This article explains how Microsoft® Transaction Server (MTS) 1.0 eliminates the need to work on low-level programming when building server applications, allowing developers to focus primarily on the server business logic. To illustrate MTS design and implementation decisions, we've built a sample Customer Maintenance program that exhibits the fundamental MTS development and deployment tasks. As we walk through the client and server code, we will point out requirements and suggestions for building your applications according to the MTS programming model. We've provided a glossary of MTS terminology in the sidebar "An MTS Glossary" for your general reference.

What is MTS?

MTS is a component-based programming model and runtime environment for developing, deploying, and managing high-performance, scalable, and robust enterprise Internet and intranet server applications. MTS 1.0, which was released in December 1996, combines the power, flexibility, and low cost of desktop applications with the mission-critical transaction processing features previously found on high-end mainframes. MTS requires Microsoft Windows NT
® 4.0 and accommodates both Windows NT and Windows® 95-based clients (with DCOM support).

MTS Components

Because MTS uses a component-based application development model with a transaction processing runtime infrastructure, you break down your business logic into ActiveX
components that can be updated and managed easily. You use your favorite development tool—Visual Basic®, Visual C++®, Visual J++, COBOL, Powerbuilder, Optima++, or Vision Builder—to build ActiveX single-user components as in-process DLLs. The DLLs are then installed into the MTS runtime environment for execution. You can create your application from components you build yourself, components you share with other applications, or components you buy from a third party.

MTS Explorer

The MTS Explorer helps you package, deploy, and administer your applications. MTS applications consist of one or more packages—a set of components that perform related application functions that are organized into one deployment unit. You can use the MTS Explorer's graphical user interface to perform development, deployment, and administration tasks on your package files. The MTS Explorer hierarchy depicts how the items in the runtime environment are organized so that you can manipulate your applications on the package, component, interface, and method levels. The MTS Explorer interface lets you perform tasks ranging from creating a new package to providing a brief description of a method on an interface for administrators to reference.

MTS Application Clients

With MTS, you have a choice of clients. MTS supports HTML browser clients and Win32
® clients built using any of the development tools mentioned previously. Figure 1 shows how the two client types communicate with MTS components. A Win32 client communicates over DCOM with an MTS component running in the MTS runtime environment. A browser client communicates with Microsoft Internet Information Server (IIS) or any other Internet server capable of invoking ActiveX components. For example, you can write Active Server Pages (ASP) scripts to invoke ActiveX components running in MTS.

Figure 1:  Three-tier Architecture with MTS
Figure 1:  Three-tier Architecture with MTS

MTS Runtime Environment
Components in an MTS application execute in the MTS runtime environment. This runtime infrastructure:
  • Manages system resources, including processes, threads, and database connections so that your server application can scale to many simultaneous users.
  • Manages server component creation, execution, and deletion.
  • Automatically initiates and controls transactions to make your application reliable.
  • Implements security so that unauthorized users cannot access your application.
  • Provides tools for configuration, management, and deployment.
MTS components can access data using ODBC. Anything layered above ODBC may also be used to access data, including ActiveX Data Objects (ADO), OLE DB provider for ODBC, and Remote Data Objects (RDO). Since ODBC 3.0 Driver Manager is an MTS resource dispenser, data accessed via ODBC is automatically protected by your object's transaction. In order for this to work, an ODBC-compliant database must have a thread-safe driver that operates without thread affinity.
If ODBC is used from within a transactional component, then the ODBC driver must also support the SQL_ATTR_ ENLIST_IN_DTC connection attribute. This is how the ODBC Driver Manager asks the ODBC driver to enlist a connection on a transaction. You can make your component transactional by setting the transaction property for your component in the MTS Explorer.
Currently, SQL Server
6.5 is the only database with an ODBC driver that satisfies both criteria. Many databases support the first criteria and are working on providing support for the second. If you are working with a database that does not have a resource dispenser that can recognize MTS transactions, contact your database vendor to obtain the required support.
Other MTS resource dispensers include the Microsoft beta products codenamed "Cedar" and "Falcon." Cedar is used to access CICS and IMS transaction monitor mainframes. Falcon (Microsoft MSMQ) is a message queuing system (see http://www.microsoft.com/msmq/). Since Cedar and MSMQ are resource dispensers, any work done is guaranteed to be protected by the object's transaction when used by an MTS component. The MTS Beta SDK can be used to build additional resource dispensers.

MTS Transaction Coordinator

MTS uses the services of Microsoft Distributed Transaction Coordinator (DTC) for transaction coordination. DTC is a system service that coordinates transactions that span multiple resource managers. Work can be committed as a single transaction even if it spans multiple resource managers, potentially on separate machines. DTC was first released as part of Microsoft SQL Server 6.5 and is included as part of MTS. It implements a two-phase commit protocol that ensures the transaction outcome (either commit or abort) is consistent across all resource managers involved in a transaction. DTC supports resource managers that implement OLE transactions, X/Open XA protocols, and LU 6.2 Sync Level 2.

Customer Maintenance Sample

To illustrate the process of building applications to the MTS programming model, we wrote a simple, three-tier sample application called Customer Maintenance that updates customer information in a database. We built Customer Maintenance using Visual Basic 5.0 Enterprise Edition, ADO, and SQL Server 6.5 for the database. Figure 2 illustrates the architecture of the sample application.
Figure 2  Customer Maintenance Architecture
Figure 2 Customer Maintenance Architecture

The user interface of the Customer Maintenance client consists of two forms for data entry. Figure 3 shows the update form to add or modify customer information stored in the customer table of the database. The customer form contains the subroutines shown in Figure 4. If the user selects Search, a second form is displayed to provide search capability across the database. Users can enter any part of a customer name to display a list of customers, and then select the customer name for modification. Figure 5 shows the user interface for searching customer records, and Figure 6 lists the subroutines contained in the form.
Figure 3 Update Form
Figure 3 Update Form

Note that in the client code (see Figure 7), the ERROR_NUMBER constant is used for setting the error number in the application. The ERROR_ NUMBER's value is set to a value higher than the standard Visual Basic error numbers to avoid any conflicts, and can be used to generate application errors. The client code also contains a constant, strDSN, that points to the location of the DSN file used for this application. The DSN file is a text file that contains information about the database to be used for this application.
Figure 5 Searching Customer Records
Figure 5 Searching Customer Records

So, what else do you need to do to make MTS work with a Win32 client? This is the best part: there is nothing specific about a client communicating directly with an MTS middle-tier server other than meeting the standard ActiveX client programming requirements.

Customer Server Component

On the server, the sample application contains a single component, MTS_Customers.Customers, that handles access and update requests from the client. The server Customer component is a middle-tier object that uses methods for finding, adding, and updating customer information in a database. The Customer component uses the "Requires a transaction" setting (we'll tell you how to set this property in the MTS Explorer later), which means that all work done in the component will be protected by a transaction. The component can run in a transaction all by itself or may also be called as part of a larger transaction. The component itself only needs to care about its own work.
The component will essentially place its "vote" on the outcome of the transaction based on the success or failure of its own work. If the component is happy with the outcome, it will execute an MTS method to commit the transaction. Otherwise, the component will execute an MTS method to abort the transaction. The important point here is that the component does not ever need to know about what the other components are doing or the outcome of their work. Figure 8 shows the methods used in the Customer object. (See the "MTS Transactions" sidebar for a more detailed discussion.)
The first part of the server component sets the return value of the method LookupCustomerByLastName to ADODB.Recordset because we are going to remote a recordset back to the client. Note that we pass in the fileDSN for the database. By using the fileDSN, you can avoid hardcoding system DSN information into your program.

 Option Explicit
 Public Const ERROR_NUMBER=
   vbObjectError + 0
 ' we always return the
 ' same error number

 Option Explicit
 Public Function
   LookupCustomerByLastName
   (ByVal fileDSN As String,
    ByVal vLastName) As ADODB.Recordset
First, we need to get a reference to an object context for our server component. The object context is an intrinsic MTS runtime component that stores data specific to a component instance (including security and transaction information). ObjectContext also exposes methods that make up the MTS programming model.

    Dim objContext As
       ObjectContext
    Set objContext =
       GetObjectContext

    On Error GoTo
       ErrorHandler
We set the cursor location property on the customer recordset to the value adUseClientBatch so the recordset can be remoted back to the client. We then use a standard SQL query on the database to pull records of customers with the specified last name.
We use SetComplete on objContext to indicate to MTS that we are finished with this piece of work and no longer need the state in this component. This means a component can be returned to its initial state for future method invocations. Note that we have not written any explicit code supporting transactions. The MTS runtime environment handles transaction support if you specify (in the MTS Explorer) that your components require transactions. We'll show you how to assign transactional settings when we deploy the Customer Maintenance package.
SetComplete also tells the MTS runtime that any resource manager changes can be committed. SetAbort tells the MTS runtime that the component is done with its work, but that any resource manager changes should be rolled back (aborted). If this component was part of a larger transaction, then the changes would be committed when all the components had completed their work successfully (see Figure 9).
Next, we implement the LookupCustomerByEMail method (see Figure 10), which checks the database for a specified email string and returns a recordset to the client. To add a customer to the database, we use the Add method, which takes a number of parameters. To avoid expensive network round-trips, we recommend that you pass parameters instead of setting properties on the object.
We use a Connection component because we are not going to be returning a recordset to the client (see Figure 11). The Update method is very similar to the Add method. Again, we use the Connection component (see Figure 12).
You've probably noticed a general pattern in the implementation of each of the methods in the Customer server component—each method shares the following infrastructure in the code: Public Sub DoWork()

     Dim objContext As ObjectContext
     Set objContext = GetObjectContext

     ' Do work.

     ' Everything okay.

     objContext.SetComplete

     Exit Sub

 ErrorHandler:

     ' Cleanup object on the way out
     objContext.SetAbort

     ' Report Error information

 End Sub
In general, the majority of MTS application methods can be written for MTS components by following these steps:
  1. Get the MTS ObjectContext.
  2. Do work.
  3. If there is no error, tell MTS you are done and consistent using ObjectContext.SetComplete.
  4. Otherwise (Error), tell MTS you are done and are inconsistent using ObjectContext.SetAbort.
The Customer component is a simple but complete representation of a typical MTS component. We did not include the methods associated with creating subcomponents or programmatic security in this sample. (A discussion of Just-In-Time activation appears in the "Just-In-Time Activation" sidebar.)

Preparing for Deployment

When building your application, think about development and deployment as two separate stages. Applications are partitioned into package files and then deployed and administered by the MTS Explorer. A package is an abstraction-representing component associated by security and fault isolation as well as a physical file format. The package file contains component and application information. The package file and corresponding component DLLs represent the deployable unit, which is distributed to one or more middle-tier server machines. Note that an MTS application can consist of one or more packages, just as a package can contain one or more components.
When creating an MTS application, you should carefully consider the design and deployment implications for package topology, partitioning of components across packages, package security configuration, and property configuration per component (such as transactions or security). The "Package Design" sidebar gives you a few pointers for designing your package application topology.
Figure 13 Package Wizard
Figure 13 Package Wizard

Opening the MTS Explorer, we selected the Packages Installed folder in the MTS Explorer hierarchy and started the Package Wizard by selecting File|New. Figure 13 illustrates how you can either create a new package or install a prebuilt package (such as a package provided by a third-party developer).
Figure 14 Component Wizard
Figure 14 Component Wizard

After we created and named the new package, we installed the MTS_Customer.DLL file into the package as a component. The MTS Explorer has an Install Component Wizard that walks you through the installation of a component (see Figure 14). You can also drag and drop your DLL into the component pane of the MTS Explorer to add a component to a package (see Figure 15).
Figure 15 Adding a component to a package
Figure 15 Adding a component to a package

After we set up our package, we right-clicked on the new component in the package to bring up the Properties page, which allows you to define transaction support, security, and activation. We set the transactions setting to "Requires a transaction" so that our component will automatically start a new transaction if one doesn't already exist (see Figure 16). Note here that selecting a single radio button on a property page enables transactions in your component. You don't have to write any code to define the scope of a transaction, such as Begin Transaction or End Transaction, because that functionality is built into MTS, just like declarative security and a number of other features.
Figure 16 Component Property Page
Figure 16 Component Property Page

Figure 17 The Client Subdirectory
Figure 17 The Client Subdirectory
Once we set up our package, we used the export function in the MTS Explorer to export that package to a local directory. This generates a subdirectory called clients that contains a client install executable (see Figure 17). You can distribute that client executable through a share, a Web page, or email.

Deploying the Application

The Customer Maintenance sample application consists of five files (not including database configuration). On the client side, both CustomerMaint.exe and Customers.exe are deployed to a set of client machines. MTS handles the configuration of client applications for server packages, while the distributor is responsible for delivering the client executable to users. When the user runs Customers.exe, the client install file will configure the client machine to activate the Customer component on a remote server.
Note that the current implementation of client install configures the remote server as the server machine that created the package. Alternatively, you can use the DCOM configuration utility (DCOMCNFG.EXE) to modify the remote server to which the client connects.
The other two files, MTS_Customer.dll and Customers.pak, are deployed to one or more server machines. You can distribute these server components across multiple servers and statically bind specific client machines to specific servers. Balancing the load across several server machines increases application performance and scalability.
Once Customers.pak and MTS_Customer.dll are physically on or accessible from the server machine, the MTS Explorer can be used to install the Customers package in-to MTS. The MTS Explorer provides remote administration, so packages can be deployed across several servers from a single instance of MTS Explorer.
If you used declarative security on your application, the next step in setting up the MTS server is to configure each security role defined in the Customer package with specific Windows NT users and groups. Package developers are encouraged to provide documentation for those deploying MTS applications (specifically, detailed information on security roles and call authorization between components and component interfaces). If a package does not contain documentation about security roles, you can use the MTS Explorer to browse role information.

Monitoring the Application

You can also use the MTS Explorer to monitor your applications. After you have deployed the Customer Maintenance application across a set of clients and servers, you can review activity on one or more servers. The component status view provides information per component:
Objects The total number of objects that have been allocated within the server process.
Activated The total number of objects being used by clients.
In Call The total number of objects that are currently executing a client call.
Figure 18 Transaction Statistics
Figure 18 Transaction Statistics

In addition to component status, you can monitor transaction status using the Transaction Statistics view (see Figure 18). Statistics include current active transactions, total committed transactions, and total aborted transactions.

Conclusion

We just stepped through the implementation, packaging, and deployment of a simple three-tier MTS application. To really learn what MTS is all about, what problems it solves, and what issues it raises, you must build an MTS application on your own. Start out with an application that is not critical-path for your business, but performs a specific business function. We recommend starting a "3-2-1"effort, meaning that you identify a business application that can be implemented using a three-tier architecture, using two people, in one month. This will get you comfortable with MTS and by the end of the project you will have assembled a working enterprise application.
If you don't already have MTS 1.0, you can download an evaluation copy from http://www.microsoft.com/transaction/. Try it for yourself and see what the developer community is beginning to realize: if you're not using MTS, you're coding more than you should for server applications.

See the "Learning More About Microsoft Transaction Server" sidebar.

From the August 1997 issue of Microsoft Systems Journal. Get it at your local newsstand, or better yet, subscribe.

© 1997 Microsoft Corporation. All rights reserved. Legal Notices.

© 2017 Microsoft Corporation. All rights reserved. Contact Us |Terms of Use |Trademarks |Privacy & Cookies
Microsoft