Age-old COM+/MTS Tips

June 2, 2004

Here are some pointers for writing VB COM components for running under IIS and MTS (that’s Internet Information Services and Microsoft Transaction Server).  These tips primarily deal with VB6 and IIS 4 & 5 (.Net tips coming soon).  Please note that whenever I speak of MTS, I am also referring to COM+.

ALWAYS make your component Apartment Threaded or Free Threaded.
Since VB doesn’t allow you to create Free threaded components, you are limited to Apartment Threading. Single Threading should not be used.

Turn on Unattended Execution and Retain In Memory options
VB Components running under MTS MUST have the Unattended Execution, and Retain In Memory options set. There are several documented bugs in Microsoft’s knowledge base that all recommend setting the retain in memory option.  It has been discovered that when running heavy load with DCOM under MTS and NT4, VB components without this option set WILL bring down the server. 

NEVER mix Apartment and Single threaded components in the same MTS package.
This WILL cause all kinds of errors, and system instability.

Always maintain binary compatibility
The component tab of the project property box has this setting.  I can’t stress enough how important this is. Every time you compile you should double check to make sure this is set.  If you must break binary compatibility, first consider the alternatives, e.g., adding a new slightly different method instead of changing an existing method or creating a new version of the component with a slightly different name. If you still must break compatibility YOU MUST NOTIFY whoever will be registering the component.  There are additional registry clean-up steps that must be performed when a component with the same name but different Class ID is registered.  IF these steps are not performed, MTS will very likely become unstable. I know this from experience. Trust me, it really messes things up. 

Group components within packages based on use
When determining what package to put your components in, try to group them in packages based on usage. If the Employee component makes heavy use of the Donut component, placing both components in the same package will reduce COM marshalling across process spaces. This results in much greater performance.
Note: ADO is not an MTS component. It is MTS aware, but does not actually run under MTS.

ADO property values get lost
When passing ADO recordsets between components registered in different MTS packages, or between a component in an MTS package and ASP, the sort and filter property values are lost. This happens whenver an ADO object is marshalled across processes.

Keep your components stateless
When the transaction your component is participating in is finished, MTS destroys all instances of all MTS objects participating in the transaction, this cleans up any and all resources being used.  It may not appear that way, since references your ASP code has to these objects remain valid.  This is merely because MTS does some behind-the-scenes manipulation, swapping the just finished instance for a new or recycled instance. This means your object can never rely on property values remaining between method calls. 

Given the item above, object properties should not be counted on to be accurate with an object running under MTS.

Close recordsets and database connections before exiting methods
This is a very important resource issue. You may think that VB should clean up these references when they go out of scope, but search the Microsoft knowledgebase, and you will find many entries urging you to do this. From personal experience, I can tell you — they are correct.  So, be sure to close any recordset and/or database connections within your methods before exiting.

MTS objects and the Class_initialize/Class_terminate events
You should not put code in the Class_Initialize and Class_Terminate events of an MTS component that attempts to access the object or its corresponding context object. The Visual Basic run-time environment calls Class_Initialize before the object and its context are activated by MTS, so any operations that Class_Initialize attempts to perform on the MTS object context will fail. Similarly, the object context is deactivated before Class_Terminate is called, so operations that this event attempts on the object context will also fail.

Wrapping up
This is a just small sampling of the little things that can make or break your COM+/MTS ASP-based application. Some of these, as you may have seen, can literally take your server down on a regular basis, so please be wary.