> That's not exactly true. if the client disposes the component as appropriate
> by calling IDisposable::Dispose() or ServicedComponent::DisposeObject(),
> that will deactivate the component and trigger the commit/rollback.
Hi Ed,
> So if the client makes several calls to transactional component which
> doesn't have [AutoComplete] and after it invokes Dispose() (which is a normal
> pattern of COM+ components using, isn't it), all these transactions will
> commit/rollback immediatedly after Dispose()?
Maybe, maybe not... it depends on whether the object in question is the root
of the transaction stream.
Let me put it all this way:
While a transaction can spawn multiple contexts, the first context it was
created in is known as the root of the transaction stream. Regardless of how
many components are involved in the transaction, and how many of them vote
on the transaction, COM+ will only decide to try to commit or try to
rollback the transaction *after* it deactivates the object in the context
that is the root of the transaction stream (that's why the object itself can
never know the result of the transaction!).
Now, there are several ways the object could be deactivated:
1- It uses [AutoComplete], in which case COM+ will deactivate the component
right after the call to the method exits (and COM+ will decide whether to
commit or rollback depending on the state of the transaction so far, and
whether the method threw an exception or returned normally).
2- It does *not* use [AutoComplete], but rather uses
ContextUtil.SetComplete()/SetAbort() or sets ContextUtil.DeactivateOnReturn
= true.
3- The object itself doesn't do any of the two above, but rather lets the
caller decide when to do so. The caller decides by releasing all references
to the object (in COM terms), which in .NET is done by calling
IDisposable::Dispose() or ServicedComponent::DisposeObject().
Is that any clearer?

Signature
Tomas Restrepo
tomasr@mvps.org