codeproject c# .net transactionscope

c# - codeproject - ¿Cómo saber si el código está dentro de TransactionScope?



codeproject c# (2)

Esta es una forma más confiable (como dije, Transaction.Current puede configurarse manualmente y no siempre significa que realmente estemos en TransactionScope). También es posible obtener esta información con reflexión, pero la emisión de IL funciona 100 veces más rápido que la reflexión.

private Func<TransactionScope> _getCurrentScopeDelegate; bool IsInsideTransactionScope { get { if (_getCurrentScopeDelegate == null) { _getCurrentScopeDelegate = CreateGetCurrentScopeDelegate(); } TransactionScope ts = _getCurrentScopeDelegate(); return ts != null; } } private Func<TransactionScope> CreateGetCurrentScopeDelegate() { DynamicMethod getCurrentScopeDM = new DynamicMethod( "GetCurrentScope", typeof(TransactionScope), null, this.GetType(), true); Type t = typeof(Transaction).Assembly.GetType("System.Transactions.ContextData"); MethodInfo getCurrentContextDataMI = t.GetProperty( "CurrentData", BindingFlags.NonPublic | BindingFlags.Static) .GetGetMethod(true); FieldInfo currentScopeFI = t.GetField("CurrentScope", BindingFlags.NonPublic | BindingFlags.Instance); ILGenerator gen = getCurrentScopeDM.GetILGenerator(); gen.Emit(OpCodes.Call, getCurrentContextDataMI); gen.Emit(OpCodes.Ldfld, currentScopeFI); gen.Emit(OpCodes.Ret); return (Func<TransactionScope>)getCurrentScopeDM.CreateDelegate(typeof(Func<TransactionScope>)); } [Test] public void IsInsideTransactionScopeTest() { Assert.IsFalse(IsInsideTransactionScope); using (new TransactionScope()) { Assert.IsTrue(IsInsideTransactionScope); } Assert.IsFalse(IsInsideTransactionScope); }

¿Cuál es la mejor manera de saber si el bloque de código está dentro de TransactionScope?
¿Es Transaction.Current una forma confiable de hacerlo o hay alguna sutileza?
¿Es posible acceder a ContextData.CurrentData.CurrentScope interno (en System.Transactions) con reflexión? Si es así, ¿cómo?


Transaction.Current debe ser confiable; Acabo de verificar, en esto funciona bien también con transacciones suprimidas:

Console.WriteLine(Transaction.Current != null); // false using (TransactionScope tran = new TransactionScope()) { Console.WriteLine(Transaction.Current != null); // true using (TransactionScope tran2 = new TransactionScope( TransactionScopeOption.Suppress)) { Console.WriteLine(Transaction.Current != null); // false } Console.WriteLine(Transaction.Current != null); // true } Console.WriteLine(Transaction.Current != null); // false