Thursday, May 23, 2013

Be mindful of transactions when logging exceptions to a database

The idea behind transactions is this:  When an exception occurs, any database updates defined within the scope of a transaction are not committed to the database.  Either everything works or everything doesn't.  If you are logging exceptions to a database, you have to make sure your logging code is not within the scope of the transaction where the exception is occurring.

This can be tricky when using web services.  I would advise not using the System.EnterpriseServices.TransactionOption web method attribute to implement transactions.  This essentially includes the entire web method within the scope of a transaction.  So, your logging code would also be included in this transaction and would not be committed if an exception occurs.

Replace the attribute with the following code:

Try

    Dim MyOptions As New System.Transactions.TransactionOptions
    Dim MyScopeOption As New System.Transactions.TransactionScopeOption
    MyOptions.IsolationLevel = Transactions.IsolationLevel.ReadCommitted

    Using scope As System.Transactions.TransactionScope = _
      New System.Transactions.TransactionScope(Transactions.TransactionScopeOption.Required, _
      MyOptions)

        ...
        Code goes here
        ...

        scope.Complete()

    End Using

Catch ex As Exception

    ...
    Database logging code goes here
    ...

End Try

Note that when an exception occurs, you leave the scope of the transaction, and are free to commit your logging entries in the database.

No comments:

Post a Comment