Why have nested transaction rules changed?
I'm very annoyed by the change in nested transactions. Previously it was perfectly ok to nest a transaction with a different isolation level to the current Tx providing it didn't ask for a stronger isolation level. Now it seems it has to be exactly the same. This has made porting from Enterprise Services to System.Transaction a complete nightmare! Why the change, it makes a mockery of ambient transactions since now every component has to understand what Tx they're in...surely this is a mistake or I've missed something?
[538 byte] By [
pkr2000] at [2007-12-25]
First - a clarification for the readers - nested transactions are not currently supported. Nested TransactionScope-s are supported, and pkr2000 is referring to them.
The change to allow only the exact match of the isolation level of the current transaction and the isolation level specified by the TransactionScope about to enter is by design. The previous design in EnterpriseServices had a few issues. Imagine the ambient transaction having the isolation level set to Serializable and imagine that a new piece of code (for instance in a new library added to the project) is called under this transaction. If that new piece of code is using TransactionScope with isolation level set to ReadUncommitted, then that meant that it expects a certain level of performance and a certain level of locking. If we would allow the Serializable transaction to get in, those expectations might not be met and this behavior can lead to performance degradation and more than that, possible deadlocks. I hope this helps.
Thanks for the reply and the clarification.
I empathise with the dilema of, should we do exactly what the nested component wants, should we error or should we enlist it but at our current isolation level. Personally I believe the later is the best option especially if the nested component could ask what the isolation level actually was after the call or even have an option to say "I will only accept this isolation level". I agree that this logic would be something to debate, however what puzzles me is that the decision was already made in the Enterprise Services mechanism and since the dilema hasn't changed why has the resulting behaviour been changed now? Also not only has it been changed, making porting existing code harder (although I can supply a workaround should anyone want it - based on code written by Florin Lazar), but I've not seen any "Gotcha" documentation to point out that there is this fundamental difference.
So I feel that System.Transactions has needlessly broken "existing code" (i.e. wannabe ported code) when it could so easily have provided mechanisms to support either solution to the, "what should I do" dilema. All I ask for is a quick hot-fix of an extra option; EnlistBehaviour {MustBeTheSame [Default]| AutoPromoteLowerRequestToCurrent}
...come on that must be easy for Microsoft to issue that 
AT LEAST, there should be a "SuggestedIsolationLevel" on TransactionOptions. With this, the transaction scope would be able to use a less expensive isolation level when it is possible. Or as pkr2000 said a "AutoPromoteLowerRequestToCurrent"...
Why? I'm developing a huge framework for an ERP and many reads (selects) on peripheral tables do not need to use Serializable isolation level. Actually, it is exactly what I don't want since then these tables are frequently read. But reads are made inside a method that use TransactionScope and inheritance the isolation level from above. The only choose that I have is to use “TransactionScopeOption.Suppress” for these reads. I would prefer to use Isolation Level as “IsolationLevel.ReadCommitted” for it.
I didn’t know that EnterpriseServices were able to use different isolation level. It’s a shame that they’ve changed this behavior.