MTS provides a distributed run-time environment in which you run business objects. Figure 9-1 shows the relationship between the client applications and the distributed objects running in the MTS environment. As you can see, MTS provides the container application (mtx.exe) that acts as a surrogate process. MTS objects are deployed using COM-style DLLs that are loaded into the MTS environment.
Objects are deployed in the MTS run-time environment using components and packages. Each computer running MTS stores configuration information about its components and packages in a section of the Windows Registry known as the MTS catalog. You can inspect this catalog by locating the following path in the Registry:
Figure 9-1. MTS provides a surrogate process for each server package that can load and run distributed business objects on behalf of clients throughout the network.
MTS uses the term component to mean a creatable class, which is the same as a COM coclass. To run your Visual Basic objects in the MTS run-time environment, you must create an ActiveX DLL with public MultiUse classes. After you install the DLL, each of your classes is recognized as an MTS component.
All MTS components are distributed in packages. A package is a named unit of deployment that contains MTS components. When a package is created, the MTS system assigns it a GUID for identification and creates a profile in the catalog that contains a set of properties. Before you can install a DLL in the MTS environment, you must create a new package or locate an existing one.
MTS supports two types of packages. A server package provides a surrogate process for running MTS objects; it represents a distributed application. When a client activates an object from a server package, the MTS system activates and runs the object in a package-specific instance of the MTS container application mtx.exe, as shown in Figure 9-1.
Because a server package runs in its own isolated process, you can see it as both a security domain and a fault isolation domain. You can partition a distributed application into several server packages to make it more robust and secure. See Chapter 11 for guidance on how to decide whether to run a distributed application in a single process or partition it into multiple server packages.
A library package, unlike a server package, doesn't provide its own surrogate process. Instead, objects created from a library package are loaded into the address space of the client application that created them. Library packages provide a way to share component code across several server packages and to run MTS objects in environments other than the MTS container application mtx.exe.
Both server packages and library packages rely on the services of the MTS Executive, which lives in mtxex.dll. This DLL contains most of the logic for the sophisticated run-time services provided by MTS. Because these run-time services are maintained in a DLL, MTS can offer flexibility in deployment.
You'll often use server packages that rely on both mtx.exe and mtxex.dll. However, if a client application creates an object from an MTS library package, the MTS run time is loaded into the client's address space. The Web Server process for Internet Information Server (IIS), Inetinfo.exe, is an example of a client application that exploits the MTS run-time environment by loading mtxex.dll into its address space. While there are deployment scenarios in which library packages are more appropriate than server packages, this chapter focuses on using server packages because it's a better way to start learning about how MTS really works.
You create MTS components with Visual Basic by adding public MultiUse classes to an ActiveX DLL. Be sure you leave the threading model of your ActiveX DLL project set to the default, which is Apartment Threaded. After building your DLL, you can install it in the MTS run-time environment using the MTS Explorer. You can launch the MTS Explorer from the system's Start menu by selecting Programs, then Windows NT 4.0 Option Pack, and then Microsoft Transaction Server. In the Microsoft Transaction Server group, click Transaction Server Explorer.
The MTS Explorer has a tree view control in the left pane, which includes a node named Computers (as shown in Figure 9-2). All of the computers that can be administered from the local machine are listed here. By default, only the local computer is registered under the name My Computer. If you want to add other remote computers, you can right-click on the Computers folder and choose New.
By expanding the tree view under My Computer, you can see a folder named Packages Installed. When you expand this folder, you can see a list of all the packages on your local machine. To create a new package, you click once on the Packages Installed folder. You then right-click on the folder and choose New and then Package.
Figure 9-2. Using the MTS Explorer, you can install in the MTS run-time environment an ActiveX DLL that you created with Visual Basic. Each MultiUse class in your DLL becomes an MTS component.
Let's create a new server package. After you choose the New Package command, you'll see a series of dialog boxes. The first dialog box asks you whether you want to create an empty package or install a prebuilt package from an MTS package script file. Specify that you want to create an empty package. In the next dialog box, enter a name for the new package and then click Next. In the last dialog box, select which user account will serve as the package's identity. You can either select the name of a Windows NT user account or choose to run the package under the identity of the interactive user. Select a user account, and then click Finish to create the package. Carefully consider which user account you pick because it will serve as the package's security principal.
I highly recommend using a dedicated user account in a production environment. When selecting the package's identity, you can select a user account from the local computer or one from a Windows NT domain. In the development environment, however, you might find it quick and convenient to run the package under the identity of the interactive user. Your business objects will run with the same set of permissions as your Windows NT user account, and you can use some of your old development tricks. For example, you can display message boxes while debugging your MTS components.
In Chapter 8, you saw that Distributed COM let you configure an application to run under the identity of the launching user. MTS doesn't allow this option because it would require running separate instances of a server package on one machine for each connected user. MTS allows only a single instance of any package to run on any computer at a time. Running a package under the identity of the launching user doesn't make any sense because only the first client who activates an object can use that server package.
After you click Finish, your new server package will be included in the Packages Installed list. You can examine and modify more of the server package's properties by right-clicking on it in the left pane of MTS Explorer and choosing Properties. This brings up a tabbed dialog box, in which you can perform actions such as configuring security, changing the package's identity, and switching back and forth between a server package and a library package.
Once you create a new package or locate an existing package, you can install your ActiveX DLL. The easiest way to do this is by expanding the package's folder, selecting the Components folder, and then dragging and dropping your ActiveX DLL file onto the right pane of the MTS Explorer. The MTS system will automatically configure all the MultiUse classes in the DLL. Each class will be recognized as an MTS component. After your DLL is installed, you'll see your MTS components in the MTS Explorer, as shown earlier in Figure 9-2.
MTS also lets you install a subset of components from a DLL. For example, if a DLL contains three classes, you can install two classes in one package and a third class in another package. You do this by right-clicking on the component folder in the left pane and choosing New. In the dialog box that appears, you can add components individually. While you can install components from one DLL in multiple packages, this makes distributing updates trickier and more error prone. You might consider designing each DLL so that all its classes are targeted for one specific package. This isn't your only option, but it can make things easier in both the development and production environments.
Each MTS component is based on a coclass and therefore has an associated class ID (CLSID). A client application activates an MTS object by calling in to the Service Control Manager (SCM) and passing a CLSID and an interface ID (IID), just as it does during any other COM activation request. When you install a component in a server package, the MTS system changes the Registry entries of its CLSIDs to redirect activation requests to a package-specific instance of the MTS container application.
Let's examine how activation is accomplished in an MTS application. When a client application running outside the MTS environment activates an MTS object, it's known as a base client. A Visual Basic application acting as a base client can activate an MTS object using either the New operator or the CreateObject function. When the base client attempts to activate a new object, the request is initially sent to the SCM on the client machine. The client-side SCM forwards the client's activation request to the SCM of the computer running the MTS application. The server-side SCM responds by making a local activation request on the CLSID. Up to this point, the activation sequence is just like any other in Distributed COM.
Now here's where MTS begins to get a little tricky behind the scenes. When you installed the DLL in a server package with the MTS Explorer, the MTS system modified the Registry settings for each CLSID to change the routing of every activation request. Each CLSID was given a [LocalServer32] subkey with the following path:
The GUID that follows mtx.exe in the command line identifies a specific MTS package. If an instance of this server package is already running, the server-side SCM calls in to the process and negotiates the creation of a new MTS object by passing the requested CLSID. If the package doesn't have a process running, the SCM launches a new instance of mtx.exe and then negotiates the activation of a new MTS object. In either case, the new object is created and a connection is established with the base client. As in the case of any other out-of-process connection involving Distributed COM, a proxy/stub layer is introduced between the client and the object.
In the short history of COM, one of the most painful and problematic areas of deploying distributed applications has been the configuration of computers in a networked environment. Chapter 8 explained what you must configure on each server-side computer and each client-side computer. The MTS Explorer makes it much easier to handle setup details that system-supplied utilities can't configure. You don't have to rely on Dcomcnfg.exe, nor need you worry about creating your own AppIDs by hand. The MTS system creates a hidden AppID for every server package. You can handle all the administration of security and identity using the MTS Explorer.
MTS also helps automate the configuration of the computers involved in a distributed application. It does this by creating both server-side and client-side setup programs. When you right-click on a package in the MTS Explorer and choose the Export command, MTS generates a server-side setup script file with the .pak extension.
The .pak file contains setup information about the package, such as security details and a list of every component and every DLL. During the export process, MTS copies the .pak file and all the necessary DLLs for deploying the package into the directory of your choice. This makes it convenient to move an application from a development workstation to a production server. It also gives software vendors an easy way to install their MTS applications at a customer site. Note that software vendors can also create setup programs to create packages and install components by programming against a set of catalog objects exposed by MTS.
When you export a package, MTS also generates a client-side setup program in the \clients subdirectory in the directory containing the .pak file. This makes it easy to set up the computers that will run base client applications against your server packages. When you run this setup program from any Windows computer that has Distributed COM, it configures the Registry with an AppID as well as the required CLSIDs and IIDs. It also installs the required type libraries, which enables the universal marshaler to create proxies at run time.
By default, the client-side setup program directs all base clients to activate MTS objects on the computer on which the Export command has been run. However, by changing the Remote Server Name property, you can direct client applications to activate their objects on any MTS server in the network. You can find the Remote Server Name property for your computer by right-clicking My Computer in MTS Explorer, choosing Properties, and selecting the Options tab.
MTS offers another powerful way to reconfigure a distributed application once it has been put into production. When a network is running several MTS computers, an administrator can push and pull components between computers by dragging and dropping components across machines using the MTS Explorer. You can redirect activation requests throughout the enterprise from a single desktop, and you can balance the processing load between servers and divert activation requests when one system fails. You can push and pull components only if all the machines involved are running MTS. MTS can run on Windows NT Server, Windows NT Workstation, Windows 95, and Windows 98. For more information about reconfiguring remote components from MTS Explorer, see the MTS documentation.