Cuando usamos una transacción de System.Transactions (creando TransationScope para una instancia) de forma predeterminada todas las conexiones Sql (System.Data.SqlClient.SqlConnection) (pero no es la verdadera para Oracle.DataAccess.OracleConnection) se alistan en la apertura. Eso se llama enrolamiento automático. Buena característica. Pero se puede desactivar a través del parámetro de una cadena de conexión (enlist = false). En ese caso, la conexión que se abre no se alistó. Pero puede enlistarse manualmente más tarde. Así que mi pregunta es: para alguna instancia de SqlConnection dada, ¿cómo puedo determinar si esa conexión se enlistó o no (en un System.Transaction). Puedo mirar la cadena de conexión para el parámetro. Pero esto no funcionará porque, como dije, la conexión podría enlistarse manualmente.¿Cómo se determina si SqlConnection se alistó en un System.Transactions 'tx o no?
Respuesta
El marco no parece permitir eso.
Tal vez podríamos discutir por qué necesita saber esta información? Las TransactionScopeOptions le dan cierta flexibilidad sobre cuándo crear transacciones.
Sin embargo, rechazando "no" como respuesta, una pequeña fuente navegando más tarde y he creado este código, que SI FUNCIONA. Tenga en cuenta que este código podría dejar de funcionar en cualquier momento con parches en el marco.
static bool IsEnlisted(SqlConnection sqlConnection)
{
object innerConnection = typeof(SqlConnection).GetField("_innerConnection", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).GetValue(sqlConnection);
var enlistedTransactionField =
EnumerateInheritanceChain(innerConnection.GetType())
.Select(t => t.GetField("_enlistedTransaction", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
.Where(fi => fi != null)
.First();
object enlistedTransaction = enlistedTransactionField.GetValue(innerConnection);
return enlistedTransaction != null;
}
static IEnumerable<Type> EnumerateInheritanceChain(Type root)
{
for (Type current = root; current != null; current = current.BaseType)
yield return current;
}
De nuevo, esto está haciendo uso de variables privadas y clases internas dentro del marco .NET. Si bien funciona hoy, puede que no mañana.
+1 como advertencia "puede que no funcione mañana". – TcKs
¿Hoy está funcionando? –
Hoy está funcionando. – TheSoftwareJedi
- 1. ¿Cómo se determina si CKEditor está cargado?
- 2. ¿Se requiere SqlCommand.Dispose() si se eliminará SqlConnection asociado?
- 3. C# HttpWebRequest - ¿Cómo se determina si se realizó HTTP 301?
- 4. ¿Cómo se determina si una lista bidimensional contiene un valor?
- 5. ¿Cómo se determina si la página emergente está abierta o no?
- 6. ¿Cómo se determina si dos nodos están conectados?
- 7. determina programáticamente si la dirección IP se asigna mediante dhcp o se establece manualmente en java
- 8. ¿Cómo se determina si un instalador de WiX es silencioso o interactivo?
- 9. ¿Cómo se determina si Git maneja un archivo como binario o como texto?
- 10. En Java, ¿cómo se determina si se está ejecutando un subproceso?
- 11. ¿Cómo se determina si un objeto está bloqueado (sincronizado) para no bloquearlo en Java?
- 12. ¿Cómo se determina si se ha llamado a un UIViewController como ModalDialog?
- 13. ¿Cómo se determina si ParameterInfo es de tipo genérico?
- 14. ¿Se eliminará SqlConnection por GC?
- 15. .net SqlConnection no se cierra incluso dentro de un uso {}
- 16. ¿Cómo se determina si ACE o JET en una máquina con Windows usa .net?
- 17. ¿Cómo se determina si la referencia del objeto es nula?
- 18. ¿Cómo saber si un objeto se libera automáticamente o no?
- 19. ¿Cómo se determina si el binario se elimina en Mac OS X?
- 20. ¿Cómo se determina si XElement.Elements() contiene un nodo con un nombre específico?
- 21. ¿Cómo se determina el uso de stat() si un archivo es un enlace simbólico?
- 22. ¿Se cierra automáticamente una SqlConnection cuando se cierra una aplicación?
- 23. ¿Cómo se determina el tamaño del proceso?
- 24. ¿Cómo se determina el tamaño de un objeto en C++?
- 25. ¿Cómo se determina si un tipo determinado (System.Type) hereda de una clase base específica (en .Net)?
- 26. No puedo encontrar: System.Transactions Namespace
- 27. ¿Cómo se determina una SoapAction válida?
- 28. ¿Cómo se determina si dos HashSets son iguales (por valor, no por referencia)?
- 29. ¿Cómo saber si una SqlConnection tiene un SqlDataReader adjunto?
- 30. ¿Cómo se determina el valor de un bloque begin?
Buena pregunta. Mi escenario es que tengo un ensamblado que es solo un grupo de métodos estáticos que tienen un SqlConnection abierto y CRUD en él. Sería bueno hacer cumplir que SqlConnection se alistó en una transacción antes de continuar, para ayudar a proteger contra la corrupción lógica a nivel de aplicación por la persona que llama. Podemos detectar un 'Transaction.Current! = Null' y podemos detectar' SqlConnection conn! = Null', pero no podemos probar para ver si el conn se enlista en una transacción. –