Pregunta

Tengo una pregunta similar a cómo controlar Si estás en una transacción. En lugar de verificar, ¿cómo permito las transacciones anidadas?

Estoy usando la base de datos de Microsoft SQL Server con ADO.NET. He visto ejemplos usando T-SQL y ejemplos de transacciones de inicio usando Begin y usando nombres de transacciones. Al llamar a Connection.BeginTransaction, llamo a otra función en la misma conexión y llama a BeginTransaction nuevamente, lo que me da la excepción:

SqlConnection does not support parallel transactions.

Parece que muchas variantes de Microsoft permiten esto, pero no puedo entender cómo hacerlo con mi archivo .mdf.

¿Cómo permito las transacciones anidadas con una base de datos de Microsoft SQL Server usando C# y ADO.NET?

¿Fue útil?

Solución

SQL Server en su conjunto no admite transacciones anidadas. En T-SQL puede emitir un BEGIN TRAN dentro de un anterior BEGIN TRAN Pero esto es solo por conveniencia. Es solo la transacción externa lo que cuenta. El cliente .NET para SQL Server (SqlConnection) ni siquiera te permite hacer eso y lanza esta excepción cuando lo intentas.

Otros consejos

Es una idea errónea común que SQL Server admite transacciones anidadas. No es asi. Abrir múltiples transacciones y luego llamar a Commit no hace absolutamente nada. Puede escribir fácilmente algunos Test SQL para probar esto usted mismo. La única opción aquí para emular una transacción anidada es usar SavePoints.

Debo agregar que lo único que importa es cuando @@ tran_count alcanza cero es el punto en el que solo se cometerá la transacción externa.

SqlConnection conn = new SqlConnection(@"Data Source=test;Initial Catalog=test;User ID=usr;Password=pass");
conn.Open();
var com = conn.CreateCommand();

com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "INSERT INTO testTable (ParamName,ParamValue) values ('test','test');";
com.ExecuteNonQuery();
com.CommandText = "COMMIT TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "ROlLBACK TRANSACTION";
com.ExecuteNonQuery();

com.CommandText = "SELECT COUNT(*) FROM testTable ";

MessageBox.Show(string.Format("Found {0} rows.", com.ExecuteScalar()));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top