Auilding an MTS Component

This section examines the fundamentals of building components for MTS. MTS components have several important coding techniques, but describing these techniques is beyond the scope of this book. Earlier, this chapter outlined the basic coding template for MTS components. All examples in this chapter will adhere to this template. To make this even more relevant for SQL Server 2000, this chapter will focus on the pivotal elements of a data access component that allow it to participate in the transactional environment.

You can use several development tools to develop Component Object Model (COM) components for MTS. The examples in this chapter use Visual J++.

The ObjectContext

The ObjectContext is the mechanism that MTS components use to access the MTS runtime environment. The ObjectContext informs a component about the context within which it is operating. For example, a component can discover the security permissions of the client application through the ObjectContext.

The most important function of the ObjectContext is tying together the work of several components into a logical transaction. You can configure components such that if one component aborts, all the other components in the logical transaction will abort as well.

Listing 43.1 shows how a component can obtain a reference to the ctxObject using the GetObjectContext() function. The role of the calling user is also checked via the ctxObject.IsCallerInRole statement. In this case, the calling user must be in the Manager's role if the users are updating the balance of the Account table with a value greater than $500. The ctxObject.SetComplete statement informs the ObjectContext that the method was successful; the ctxObject.SetAbort statement informs the ObjectContext that the method was aborted.

Listing 43.1 Using GetObjectContext(), IsCallerInRole SetComplete, and SetAbort in Java
Package Account;
Import msado15.*;
Public class Account implements iAccount {
// Get a reference to the MTS Runtime Environment
   IObjectContext ctxObject = MTx.GetObjectContext()
// Check if user has right role for the bank trans(>$500)
   if ((lngAmount > 500 || lngAmount < -500) &&
    !ctxObject.IsCallerInRole ("Managers"))
                     throw new ComFailException ("need right role")'
// more code here that might update database files (later example)

// then finally can set complete or abort the transaction

    if (bSuccess)

Methods for Database Activities

Many MTS components include some type of data access functionality. This chapter will use data access components to demonstrate the interaction between MTS and SQL Server 2000. The same account class with a database update code is in Listing 43.2.

This code establishes a connection to the ODBC datasource named MTSSamples, which is pointing to SQL Server 2000 and the Pubs database. As you can see in Figure 43.3, the MTS installation already provided the ODBC entry. All you have to do is point it to a valid MS SQL Server with a Pubs database.

Figure 43.3. The ODBC datasource entry for MTSSamples.


At that point, the Account Java class will create the Account table in the Pubs database if the table doesn't exist. Following is the code to update the Account table's balance column with the supplied value.

Listing 43.2 Using an MTS Component for Database Access
Public class Account implements iAccount {
// Get a reference to the MTS run-time environment
   IObjectContext ctxObject = MTx.GetObjectContext()
try {
// Create ADOConnection object and initialize the connection
   adoConn = (_Connection) new Connection();
   String vDSN = "FILEDSN=MTSSamples";
   adoConn.Open (vDSN, null, null, CommandTypeEnum.adCmdUnspecified);
// Obtain the desired record set with an SQL query
    Variant   vRowCount = new Variant();
    String strSQL = "UPDATE Account SET Balance = Balance + " + lngAmount +
                  " WHERE AccountNo = " + lngAccountNo;
    adoConn.Execute (strSQL, vRowCount, - 1);

// other appropriate code like calls to other components
//   (that will be automatically enlisted)

    finally {
// then finally can set complete or abort the transaction
    if (bSuccess)

The details of the syntax are not important here; simply note the sequence of events in the function:

  1. The component obtains a reference to MTS.

  2. The component connects to needed datasources.

  3. The component performs its work, such as updates.

  4. Other components are enlisted in the transaction via the CreateInstance() function (optional).

  5. The component either completes or aborts its transaction.


A component that is hosted by MTS cannot have more than 1,024 methods.

If you look back at Figure 43.1, you can trace the actual execution path that a request takes as it executes under MTS. It is interesting to note the facility that is being touched and the action that is occurring along the way. A common sequence is as follows:

  • An MTS application is invoked from a DCOM client request.

  • The MTS application is turned into an MTS transaction request.

  • The resource dispenser determines whether any resource managers need to be enlisted and ODBC enlists them as they are referenced in a request.

  • Because resource managers are needed by this request, MS DTCs handle all requests at each resource manager location.

  • All enlisted resources are known to MTS.

  • Each resource manager processes its specific request (updates, inserts, deletes, and so on) and returns an outcome of commit or abort. Remember: MS DTC is the one handling all of the two-phased commits across multiple resource managers.

  • MTS then looks at these results before the MTS transaction completes and is either successful as a whole or not, in which case all resource managers would need to abort their individual, local transactions accordingly.

  • Finally, the success or failure is returned to the requesting client.

    Part III: SQL Server Administration
    Part IV: Transact-SQL
    Part V: SQL Server Internals and Performance Tuning
    Part VI: Additional SQL Server Features