A careful look at the MTS runtime environment will help to make
the distinctions necessary to develop an MTS-specific component. When a client
calls an MTS object, the object does not receive those calls directly. Instead,
an MTS process stands between the client and the object. This architecture allows
MTS to provide the following services:
Automatic management of object instances
MTS will automatically track all instances of objects, no matter how many clients
are using the objects. Related to this feature, MTS provides the component developer
with control over how long an object’s associated resources are kept alive.
Automatic management of processes and threads
Depending on the thread model used by the component, MTS will create threads as
necessary to ensure that object code executes efficiently.
Distributed, atomic transactions for underlying data sources
MTS allows objects to take advantage of the transaction features provided by the
underlying data services. A transaction is said to be atomic when all the work
done in association with the transaction is done as a group. In other words, if
any single aspect of the transaction fails, the entire transaction is rolled back.
Built-in user security
MTS provides a simple way for security to be applied to MTS components by taking
advantage of underlying Windows NT security structures.
MTS objects that run on the local machine of the client may run
inprocess or in separate processes configured by the server. If the object will
be running on a remote MTS machine, MTS must run it in a server process. Packages
in which components will run in-process are referred to as Library Packages. If
the components in the package are to be run out of the client process, the package
is referred to as a Server Package. Exactly how the component will run can be
configured in MTS Explorer from the package’s Properties dialog box. Figure
16.3 shows the Activation tab, which is part of the Properties window of a package
in MTS Explorer.
FIGURE 16.3 The Activation tab enables you to choose which activation type
should be applied to the package. This in turn will determine whether its components
will run in-process or as separate processes.
As previously noted, MTS will track object instances, allow a
transaction to be associated with the object, and keep track of security. Internally,
MTS does this through what is known as a Context object.
Every MTS object will always have a Context object.
Context objects are created and associated with an MTS object automatically
by the MTS runtime environment. The Context object
is used by MTS to identify any transaction that the MTS object is participating
in. It is directly involved with committing or rolling back the transactions.
Furthermore, it also maintains the state of security properties.
From a component developer’s perspective, the presence of
the Context object introduces unique elements into
COM component development. In particular, by taking advantage of the functionality
available in the Context object, a component can be
designed to be stateless. In other words, an object can be designed to release
any resources it is using for internal variables, properties, ODBC connections,
and so on. This is something that is usually done when a transaction is either
completed or when it fails. This is a departure from the way other COM components
(said to be stateful) are developed. Stateful objects retain resources until the
object is destroyed. Hence, stateless objects provide the most scalable solution.
With stateless objects, clients can create an instance of an object and use the
object to perform transactions. Because the object’s resources are released
when the transaction is complete, there is no cost in not immediately destroying
the object. Of course, there are implications for the client as well, in that
any properties lose their values when the transaction is complete.
Another core topic that helps the developer to understand the
runtime environment is, what’s known as, a Resource Dispenser. A Resource
Dispenser manages shared states for components. In other words, if components
have similar uses for the same resource, such as a global property or database
connection, they can share it. An important example is the ODBC Resource Dispenser.
The ODBC Resource Dispenser provides components with two key benefits:
Components will automatically share ODBC connections, which greatly reduces
what is traditionally considered a huge cost for enterprise applications.
If the MTS component is configured to use a transaction, the activity performed
by the ODBC connections on behalf of the component will automatically be enlisted
in the transaction.
In a nutshell, the ODBC Resource Dispenser helps to provide a reliable infrastructure
that frees the developer to focus on the business logic. A second example of a
Resource Dispenser is the Shared Property Manager. By default, each instance of
an object is isolated from other instances of the same object. In other words,
properties exposed by objects are only accessible to the client that instantiated
the object. The Shared Property Manager provides a standard way for developers
to allow MTS objects from different clients to share property information with
each other. This way, a developer can circumvent the default isolation provided
to each instance of an object.