Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Building a Better Mousetrap for COM+ (MTS) : Page 2

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.


advertisement
Appropriate MTSTransactionMode Settings

The original implementation of the code could have executed without transaction support. While this does provide a very good performance boost, it is inappropriate for this implementation. It is true that you can override the settings once the components are installed in a package, but this leads to deployment errors that can be difficult to detect.

As the purpose of my testing was to compare VB objects relying on JIT activation with VC++ objects that were pooled, it was critical to avoid introducing an apples to oranges comparison of the transaction settings. To ensure that the results were measuring the expected behavior, the settings were changed as follows:



  • IAccount - '2 - RequiresTransactions'

  • ICreateTable - '1 - NoTransactions'

  • IGetReceipt - '3 - UsesTransactions'

  • IMoveMoney - '2 - RequiresTransactions'

  • IUpdateReceipt - '4 - RequiresNewTransaction'

Implementing Effective Error Handling

VB and its associated developer community are often slammed by developers using other languages (VC++ programmers in particular). VB is often referred to as a "tinker toy" language - and I've heard much more harsh criticism over the years. Perhaps the single most significant reason is that a large percentage of VB developers fail to incorporate robust error handling into the applications, with the end result being errors are not appropriately trapped and handled.

Error handling in VB has always been a poorly covered topic, and proper treatment is not given in code samples by Microsoft. The VB6 documentation does explain the behavior to expect, but the text is obviously confusing as I continue to receive requests from participants in the VB related newsgroups on this issue. I recently wrote code to demonstrate the behavior to one gentleman who quoted a documentation snippet that seemed to contradict my experience. To quote from the VB documentation:

An "enabled" error handler is one that is turned on by an On Error statement; an "active" error handler is an enabled handler that is in the process of handling an error. If an error occurs while an error handler is active (between the occurrence of the error and a Resume, Exit Sub, Exit Function, or Exit Property statement), the current procedure's error handler can't handle the error. Control returns to the calling procedure.

As you should note, there is no mention of using a GoTo statement to resume execution at another point within a procedure while an error handler is active. In addition, one very important point is missing that clarifies the intent of the quoted documentation - you cannot use another On Error statement within an active error handler to trap errors that subsequently occur. GoTo is not a substitute for Resume - in order to change the label for the error handler in effect, it is first necessary to use a Resume to disable the active error handler; at this point an On Error statement will function as intended.

Example of an ineffective error handler:

Public Function Ineffective() As String
  On Error GoTo ErrorCreateTable

  Dim bFirstTimeThru As Boolean
  bFirstTimeThru = True

TryAgain:
  ' conditionally force an error
  If bFirstTimeThru Then
    bFirstTimeThru = False
    Err.Raise -1, , "Code transitions to ErrorHandler label"
  End If

  ' next statement has no effect if an
  ' error handler is already active

  On Error GoTo ErrorHandler

  ' alternative with same effect; uncomment to test
  ' On Error Resume Next

  ' force a secondary error
  Err.Raise -2, , "Code flow returns to caller; no return value set."

  Ineffective = "Exit with return value."
  Exit Function

ErrorCreateTable:
  ' following statement is totally ineffective
  On Error GoTo ErrorHandler

  ' do some additional work

  ' does not disable active error handler, but
  ' simply continues execution at label
  GoTo TryAgain

ErrorHandler:
  Err.Raise -3, , "As implemented, label is unreachable."
End Function

The demonstration of an ineffective error handling technique uses the labels and basic logic from Account.Post, though the code has been streamlined to clarify the point. There are a couple of different ways that the code could be modified to correct the behavior. I will demonstrate one based on what I consider to be the "proper" way, as it is my practice to only permit a single point of exit, thus ensuring that any clean up processing is always executed.

The next code sample will demonstrate the changes necessary to produce the original intent. Also, note how the code flow leaves but a single point of exit for the procedure. By implementing this as a standard practice in your procedures you can effect the equivalent of VB7's structured error handling (albeit, the code is not as clean).

Example modified to demonstrate effective error handling:

Public Function Effective() As String
  On Error GoTo ErrorCreateTable

  Dim lngError As Long
  Dim strError As String 
  Dim bFirstTimeThru As Boolean
  bFirstTimeThru = True

TryAgain:
  ' conditionally force an error
  If bFirstTimeThru Then
    bFirstTimeThru = False
    Err.Raise -1, , "Code transitions to ErrorHandler label"
  End If

  ' next statement is now effective

  On Error GoTo ErrorHandler

  ' alternative with same effect; uncomment to test
  ' On Error Resume Next

  ' force a secondary error
  Err.Raise -2, , "Code flow returns to caller; no return value set."

ExitPoint:
  On Error Resume Next
  ' perform all cleanup, such as object destruction; explicit
  ' cleanup of all objects can prevent the double-snake error
  If lngError <> -3 Then  ' explicit test for demonstration
  'If lngError <> 0 Then  ' normal test value is 0 (no error)
    On Error GoTo 0
    Effective = vbNullString
    Err.Raise lngError, , strError
  Else
    Effective = "Exit with return value - now reachable, if no errors."
  End If
  Exit Function

ErrorCreateTable:
  ' following statement is totally ineffective
  On Error GoTo ErrorHandler

  ' do some additional work

  ' disable active error handler and resume
  ' processing at designated label
  Resume TryAgain

ErrorHandler:
  lngError = Err.Number - 1
  strError = Err.Description
  Resume ExitPoint
End Function

I believe that the above procedures should clearly demonstrate the underlying behavior of VB error handling. My intent for this article was not to get completely wrapped up in error handling, but I feel that it is an important topic for COM+ (MTS) development that is often given too little focus. For a more in-depth look at real world code, compare the Post and Update methods of the sample projects that come with this article.



Comment and Contribute

 

 

 

 

 


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

 

 

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