According to the generally accepted recommendation, it is necessary to call
Dispose on a component derived from ServicedComponent, regardless of JITA or
pooling settings.  Unless you want to hold on to the component state (which
is not a good thing, but it is a topic for a different discussion)

I am running into a situation where calling Dispose() method on a
ServicedComponent causes a CONTEXT_E_ABORTED error.  Here is the error
description.

System.Runtime.InteropServices.COMException (0x8004E003): You made a method
call on a COM+ component that has a transaction that has already aborted or
in the process of aborting.

This happens only in a particular situation, where a WebService requiring a
transaction calls a ServicedComoponent1, which internally calls another
ServicedComoponent2 (both supporting transactions).  The inner
ServicedComponent2 raises an exception and, consequently, automatically
votes to abort the transaction.  When a WebService calls Dispose() on the
out ServicedComponent1, the error happens.

If calling Dispose() causes an exception, does a ServicedComponent get
properly released?

There were discussions in newsgroups without any definitive answer.  The
best I could find was:
"You don't need to call Dispose, but doing so will free some resources
earlier. If you do call Dispose on a transactional component, be prepared
for CONTEXT_E_ABORTED. To me this means don't use the "using" statement,
rather call Dispose explicitly from a Finally block, so you can wrap it in
another try block."
This quote is from Wade Mascia at Microsoft as of summer 2002.

If calling Dispose() is the key for efficient resource management, what
should I do if the transaction is aborting?  I can check for transaction
state and skip Dispose() call.  Or, as Wade recommends, I can still call
Dispose() and wrap it in a try/catch.  Is skipping Dispose() better than
calling it and causing an exception?

Oleg

Reply via email to