Estoy usando TransactionScope
para hacer un método que contiene múltiples sentencias SQL transaccionales. Ahora necesito llamar a un segundo método que también usa la misma conexión y recibo la siguiente excepción en connection.Open()
:
Acceso a la red para transacciones distribuidasGerente (MSDTC) ha sido discapacitado. Por favor habilite DTC para acceso a la red en la seguridad Configuración para MSDTC usando el administrador de servicios de componentes herramienta.
Así que este es el pseudo-código:
public static void Method1()
{
using (TransactionScope scope = new TransactionScope())
{
bool success = true; // will be set to false in an omitted catch
using (var connection = new SqlConnection(ConnectionString1))
{
// ...
if(somethingHappened)
Method2();
}
if(success)
scope.Complete();
}
}
public static void Method2()
{
using (var connection = new SqlConnection(ConnectionString1))
{
connection.Open(); // BOOOM!
// ...
}
}
Cómo evitar esta excepción sin repetir el código de Method2
en Method1
?
Respuestas
2 para la respuesta № 1Si hay más de una conexión abierta bajo la misma TransactionScope
será escalado automáticamente al DTC.
Necesita cerrar la primera conexión antes de llamar Method2
.
public static void Method1()
{
using (TransactionScope scope = new TransactionScope())
{
bool success = true; // will be set to false in an omitted catch
bool isSomethingHappened
using (var connection = new SqlConnection(ConnectionString1))
{
isSomethingHappened = // Execute query 1
}
if(somethingHappened)
Method2();
if(success)
scope.Complete();
}
}
2 para la respuesta № 2
Las conexiones anidadas bajo el mismo alcance de transacción se promoverán a una transacción distribuida.
Desde SQL Server 2008 y más, múltiples conexiones (no anidadas) en el mismo ámbito de transacción no se promocionarán a una transacción distribuida.
ver esta pregunta para más información
0 para la respuesta № 3
No conozco la respuesta precisa, pero me gustaría hacer la conexión de un miembro y hacer un seguimiento si está abierta.
Luego, en Método 1 y Método 2 obtendría la conexión a través de alguna GetConnection () que abriría la conexión en el primer uso.
Después de leer los comentarios, sugeriría un DoMethod2 privado que tome un objeto de conexión.