¿Cuál es la mejor manera de saber si el bloque de código está dentro de TransactionScope?
¿Transaction.Current es una forma real de hacerlo o hay sutilezas?
¿Es posible acceder a ContextData.CurrentData.CurrentScope (en System.Transactions) con reflexión? Si es así, ¿cómo?¿Cómo saber si el código está dentro de TransactionScope?
Respuesta
Aquí es la forma más fiable (como ya he dicho, Transaction.Current se puede ajustar de forma manual y no siempre quiere decir que estamos realmente en TransactionScope). También es posible obtener esta información con reflexión, pero emitir 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);
}
Transaction.Current
debe ser confiable; Yo sólo he comprobado, en este funciona bien con las transacciones suprimidas, también:
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
Quiero decir que la propiedad Transaction.Current se puede establecer incluso si no estamos en TransactionScope. – nightcoder
Si TransactionScope está completo, pero aún no se elimina, Syste.Transactions.Transaction.Curre arroja una excepción –
- 1. Cómo saber si el dispositivo está durmiendo
- 2. Ignorar SqlTransaction.Commit dentro de TransactionScope
- 3. ¿Cómo saber si OpenMP está funcionando?
- 4. Cómo saber si el servidor de emacs se está ejecutando
- 5. Cómo saber si un actor está inactivo
- 6. Cómo saber si el usuario está usando monitores múltiples
- 7. ¿Cómo saber si el componente VBA de Office está instalado?
- 8. ¿Cómo puedo saber si el código de Rails se está ejecutando mediante rake o script/generate?
- 9. ¿Cómo puede saber un código .NET si se está ejecutando dentro de una aplicación de servidor web?
- 10. ¿Cómo puedo saber si el CouchDB está funcionando?
- 11. ¿Cómo saber si el objeto está en NSArray?
- 12. ¿Cómo saber si el socket está abierto en PHP?
- 13. ¿Cómo saber si el objeto raphael está oculto?
- 14. ¿Cómo se manejan varias conexiones de bases de datos dentro de un TransactionScope si MSDTC está deshabilitado?
- 15. ¿Cómo saber si NSAssert está deshabilitado en versiones de lanzamiento?
- 16. Dentro de un archivo por lotes, ¿cómo puedo saber si se está ejecutando un proceso?
- 17. ¿Cómo saber si existe una imagen dentro de un paquete?
- 18. ¿Cómo puedo saber si la cámara está en uso?
- 19. ¿Cómo puedo saber si la pantalla está activada en Android?
- 20. ¿Cómo saber si la salida del comando "buscar" está vacía?
- 21. ¿Cómo puedo saber si se está mostrando ModalViewController?
- 22. ¿Cómo saber si la tarjeta SD está montada en Android?
- 23. ¿Cómo puedo saber si NSTimer está activo o no?
- 24. ¿Cómo puedo saber si un secuenciador está cerrado?
- 25. ¿Cómo saber si un proceso MySQL está atascado?
- 26. Cómo saber si un usuario está visitando "/Default.aspx" o simplemente "/"
- 27. ¿Cómo puedo saber si Matlab está ocupado cuando usa GUI?
- 28. ¿Cómo saber si un navegador está en modo "peculiar"?
- 29. prueba si el número está dentro del intervalo circular
- 30. Objeto dinámico: cómo saber si una propiedad está definida?
Me pregunto si ha cambiado su definición de "confiable" después de usar este código en producción durante cuatro años. –
Si Transaction.Current no es confiable, ¿por qué no lo hizo .Net Devs lo dejó solo? ¿Has mirado su implementación? –
Aparece en .Net 4.5 "CurrentData" se ha cambiado el nombre a "TLSCurrentData" –