简体   繁体   中英

How do I enable nested transactions with ADO.NET and SQL Server?

I have similar question to how to check if you are in a transaction . Instead of checking, how do I allow nested transactions?

I am using Microsoft SQL Server Database with ADO.NET. I have seen examples using T-SQL and examples starting transactions using begin and using transaction names. When calling connection.BeginTransaction, I call another function in the same connection, and it calls BeginTransaction again which gives me the exception:

SqlConnection does not support parallel transactions.

It appears many Microsoft variants allow this, but I can't figure out how to do it with my .mdf file.

How do I allow nested transactions with a Microsoft SQL Server Database using C# and ADO.NET?

SQL Server as a whole does not support nested transactions. In T-SQL you can issue a BEGIN TRAN inside an earlier BEGIN TRAN but this is just for convenience. It's only the outer transaction that counts. The .NET client for SQL Server ( SqlConnection ) does not even allow you to do that and throws this exception when you try.

It is a common misconception that SQL Server supports nested transactions. It does not. opening multiple transactions and then calling commit does absolutely nothing. you can easily write some test SQL to try this yourself. The only option here to emulate a nested transaction is to use Savepoints.

I should add that the only thing that matters is when @@TRAN_COUNT reaches zero is the point at which only the outer transaction will be committed.

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()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM