.net - ¿Cómo determinar si SqlConnection se alistó en un sistema.Transactions ''tx o no?
ado.net .net-2.0 (1)
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;
}
Nuevamente, esto está haciendo uso de variables privadas y clases internas dentro del framework .NET. Si bien funciona hoy, puede que no sea mañana.
Cuando utilizamos 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 enlistamiento 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. Entonces 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 ver la cadena de conexión para el parámetro. Pero esto no funcionará porque, como dije, la conexión podría enlistarse manualmente.