Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Building a Better Mousetrap for COM+ (MTS)

Michael Long shares his insight into improving the MTS Bank Sample for use under COM+. The article discusses issues with the original sample project, the changes made to improve the code, and why the changes were made. It also covers code flow related to error handling, and the impact of an active error handler on the On Error... statement. The code demonstrates techniques that are sure to improve the stability of your COM+ (MTS) components. In addition, these techniques can lead to increased scalability by helping you minimize resource leaks in the middle-tier. A must read for the VB developer looking for ways to improve his MTS development skills, or seeking to better understand error handling in VB.

couple of months back, I took it upon myself to clean up the VB Sample Bank code. The original goal was to modify the code just enough to use the objects in scalability tests to compare it against pooled objects written in VC++ and Delphi 5. However, once I opened the code and put fingers to keyboard I couldnt help but take a few more liberties, as the original source had a number of opportunities to make it better. For anyone having trouble interpreting PC double-speak - the code was a poor excuse for an MTS demo project. Of course, every module does contain a disclaimer and as the old saying goes, You get what you pay for.

Early last month I dug up the code modified in my scalability tests of the Sample Bank application for Ron Jacobs, the Platform SDK Manager at Microsoft. While I did provide some documentation of the changes, I had to allow the modified code to speak for itself in several areas. Time did not permit me to properly address the original issues, or the code changes made to correct them. As submitted, the code is much better than the original—and perhaps it will influence VB samples included in future releases of the Platform SDK. However, in the mean time I feel it would be beneficial to discuss the changes at length, and share my commentary with as broad an audience as possible.

Issues with the Original Code

The code for the original project was taken from the January 2000 Platform SDK. As no VB project was included with the OPBankSample, I located the equivalent code from the MTS samples from the Platform SDK. What I found was a project that was grossly deficient for deployment under MTS - for example:

  • The ObjectControl interface was not implemented and the associated event procedures were not included. While this is a documented "best practice" by Microsoft Support, the technique is rarely used. Most MSKB articles and Platform SDK samples do not follow the recommendation.

  • All public classes were marked '0 - NotAnMTSObject', and yet GetObjectContext was used to call SetComplete and SetAbort. While this does work to produce a stateless object, it is indicative of sloppy coding practices. In addition, to be equivalent with other Account project samples, most classes need to support transactions.

  • Failure to properly clean up resources; in many cases, the only effort at explicit clean up was made during error processing.

  • Extremely poor error handling. The UpdateReceipt.Update and Account.Post methods contained completely ineffective error handlers, demonstrating that the author lacked understanding of how VB transitions code flow during error processing. Note: this style of error handling leads to the double-snake error ("Method '~' of object '~' failed.").

  • Multiple code paths and exit points in a single procedure. While VB6 does not include a structured error handling mechanism (such as try..catch..finally), the equivalent can be implemented - though it requires a bit more code.

  • Declaration of ADO objects with the New keyword. While this only has a marginal impact on performance, it is generally considered to be a bad practice. However, given the author's error handling implementation, this is the only viable technique for minimizing secondary faults during error processing.

  • Repetitive declaration of commonly used constants within each class.

  • Failure to implement the interface used by OPBank.exe. As this was an unknown during original construction, this is not truly a fault with the original code. I could have modified the test harness (OPBank project) to accept the interface as coded. However, I feel it is a better practice to provide an immutable interface, and in this case one that fits the model for the test harness.

Some of the issues taken with the original project code come down to coding style. On the other hand, others will result in resource leaks under load or in the code not functioning as intended. The latter point is the result of totally ineffective error handling due to a failure to understand the impact of VB error handling semantics.

The Revised Code 

The revised project code demonstrates techniques for effective error handling, which as a side effect will eliminate preventable resource leaks. In addition, the objects can be debugged with object context under Windows NT 4 SP4 (or higher) and Windows 2000. Each of the issues mentioned above is addressed individually below, with supporting reference links to Microsoft documents following the article.

Implementing the ObjectControl Interface

It is considered a best practice for developing COM+ (MTS) object with VB to obtain and release context via the ObjectControl interface. Specifically, this should be performed using the ObjectControl event procedures; Class_Initialize and Class_Terminate should not be used. Prior to including the code, the appropriate library reference should be set::

  • MTS: Microsoft Transaction Server Type Library (MTxAS.DLL)

  • COM+:  COM+ Services Type Library (COMSVCS.DLL)

Example of implementing the ObjectControl interface:

Implements ObjectControl

Private m_ctxObject As ObjectContext

Private Sub ObjectControl_Activate()
  Set m_ctxObject = GetObjectContext
End Sub

Private Function ObjectControl_CanBePooled() As Boolean
  ObjectControl_CanBePooled = False
End Function

Private Sub ObjectControl_Deactivate()
  Set m_ctxObject = Nothing
End Sub

A note regarding debugging - unless you are developing on a Windows 9x machine or using VB5, disregard instructions contained in Q188919 related to Registry changes to run without context. Instead, you should correct your development environment if you experience problems, as the recommendations are no longer required for NT 4.0 SP4 (or higher) and Windows 2000.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date