c# - net - ¿Cuándo ocurre "SqlConnection no admite transacciones paralelas"?
transaction c# entity framework (2)
El mismo problema ocurre cuando se usa el método ''incorrecto'' para una transacción, esto sucedió después de actualizar a una versión más reciente de Entity Framework.
En el pasado, usábamos el siguiente método para crear una transacción y mezclar consultas de tipo de línea fuerte de tipo EF con consultas de SQL, pero como la propiedad Connection
ya no existía, reemplazamos todos los db.
con db.Database
, que estaba mal:
// previous code
db.Connection.Open();
using (var transaction = db.Connection.BeginTransaction())
{
// do stuff inside transaction
}
// changed to the following WRONG code
db.Database.Connection.Open();
using (var transaction = db.Database.Connection.BeginTransaction())
{
// do stuff inside transaction
}
En algún lugar, cambiaron el comportamiento del comportamiento de ese método de transacción con una versión más reciente de Entity Framework y la solución es usar:
db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
// do stuff inside transaction
}
Observe que la transacción ahora se está realizando en la Database
de Database
lugar de en la Connection
.
Tengo un montón de código bastante funcional que ha estado aquí durante meses y hoy vi la siguiente excepción registrada:
System.InvalidOperationException
SqlConnection does not support parallel transactions.
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(
IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlConnection.BeginTransaction(
IsolationLevel iso, String transactionName)
at my code here
y me gustaría investigar por qué se lanzó esta excepción. He leído la descripción de MSDN de BeginTransaction()
y todo lo que dice es que, a veces, esta excepción puede ser lanzada.
¿Qué significa exactamente esta excepción? ¿Cuál es la deficiencia en mi código que debería estar buscando?
Obtendrá esto si la conexión ya tiene una transacción no confirmada y vuelve a llamar a BeginTransaction.
En este ejemplo:
class Program
{
static void Main(string[] args)
{
using (SqlConnection conn = new SqlConnection("Server=.;Database=TestDb;Trusted_Connection=True;"))
{
conn.Open();
using (var tran = conn.BeginTransaction())
{
using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values (''" + DateTime.Now.ToString() + "'')", conn))
{
cmd.Transaction = tran;
cmd.ExecuteNonQuery();
}
using (var tran2 = conn.BeginTransaction()) // <-- EXCEPTION HERE
{
using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values (''INSIDE" + DateTime.Now.ToString() + "'')", conn))
{
cmd.Transaction = tran2;
cmd.ExecuteNonQuery();
}
tran2.Commit();
}
tran.Commit();
}
}
}
}
... Tengo exactamente la misma excepción en el segundo BeginTransaction.
Asegúrese de que la primera transacción se confirme o se restaure antes de la siguiente.
Si desea transacciones anidadas, es posible que TransactionScope sea el camino a seguir.