Over Christmas break, I spent a lot of time experimenting with EnterpriseServices (ES)/COMPlus, in particular with Distributed Transactions. Within our team, there were some questions that came up last week regarding ES:
1. Tim Ewald, in his excellent COMPlus book, describes the ideas of “configured” components and “nonconfigured” components. It would seem that a configured component (installed in the COMPlus catalog) can call a non-configured component and can (possibly??) enlist the nonconfigured component within a COMPlus transaction. How does this work with ES? Answer: In testing with ES, you don't necessarily need to have a class implementing the ServicedComponent interface, but you do need to reference the System.EnterpriseServices namespace in order for the Context, Activity, and Transaction to flow to the “nonconfigured” .Net component. Noting Tim Ewald's follow-up article, I did find this:
It is interesting to note that CLR objects behave exactly the opposite of how COM objects behave with respect to COMPlus context. With COM, calls to an object are always intercepted by default; all objects are context-bound. A COM object can only be context-agile if it aggregates the freethreaded marshaler (FTM) and is not the first object created in a new COMPlus context (that is, it is not the distinguished object), in which case, calls to it will not be intercepted. The benefit of this new approach is that it reduces interception overhead by ensuring that calls will be pre- and post-processed only when absolutely necessary. Specifically, if an instance of a configured class returns a reference to an instance of a nonconfigured class (an ADO. NET DataSet object, for example), calls to that object will not be intercepted. And the DataSet object doesn't have to do anything special, it just works this way.
What I saw was that when I referenced System.EnterpriseServices in the assembly metadata, then I could “reach up“ and grab the ContextId, ActivityId, and TransactionId within a class method that was not deriving ServicedComponent. Was that method in a transaction at that point or not?
2. Is it possible that a method could opt in or out of a distributed transaction? Answer: Yes. Distributed transaction enlistment can be automatic depending on the root of the transaction (with declaritive transaction support). But, within the connection string, the option “Enlist=false” can make sure enlistment doesn't happen. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconenlistingindistributedtransaction.asp for more interesting details.
These are just a couple of items. I plan on writing more regarding some of the gotchas we have found plus problems we are still puzzling through.