检查连接是否在事务中

时间:2010-05-18 09:36:54

标签: sql sql-server

我收到SqlConnection does not support parallel transactions.个异常,this answer在连接尝试打开两个事务时提到它。这正是我在做的事情。我认为嵌套的事务是可以的(我使用sqlite作为原型)。

如何检查连接是否已在交易中?我正在使用Microsoft SQL Server数据库文件。

4 个答案:

答案 0 :(得分:5)

经过一番搜索,我发现了另一个Stack Overflow question。事实证明,您无法在ADO.NET中嵌套事务。当您尝试时,您可能最终会启动两个不相关的事务,这会导致并行事务错误。

要查看某个连接当前是否在某个交易中,您可以:

var com = yourConnection.CreateCommand();
com.CommandText = "select @@TRANCOUNT";
var trancount = com.ExecuteScalar();

返回嵌套事务的数量。

请注意,您可以手动嵌套事务,而无需使用SqlTransaction对象。例如:

var com = yourConnection.CreateCommand();
com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "INSERT INTO TestTable (name) values ('Joe');";
com.ExecuteNonQuery();
com.CommandText = "COMMIT TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "ROlLBACK TRANSACTION";
com.ExecuteNonQuery();

com.CommandText = "SELECT COUNT(*) FROM TestTable";
Console.WriteLine("Found {0} rows.", com.ExecuteScalar());

这会打印0,因为嵌套的事务已完全中止。

答案 1 :(得分:2)

你是从多个线程做的吗?如果是这样,那么请求将无济于事,因为在您询问的时间和开始新事务的时间之间,其他一些线程可能已经开始了自己的事务。您将需要使用连接池来避免这种竞争条件。

答案 2 :(得分:0)

我认为当你的代码不知道时,只有Try / Catch会这样做。什么语言?

答案 3 :(得分:0)

您可以通过检查null是否为//begin transaction unless one was already started bool newTransaction = cmd.Transaction == null; if (newTransaction) cmd.Transaction = cmd.Connection.BeginTransaction(); try { // do Stuff Here cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery(); // commit if it's our to commit if (newTransaction) cmd.Transaction.Commit(); } catch (SqlException ex) { if (newTransaction && cmd.Transaction != null) cmd.Transaction.Rollback(); throw; } 来检查交易是否已打开。

然后相应地包装你的代码,这样如果一个事务已经打开,那么调用函数拥有该事务并将其提交/适当地回滚。

{{1}}

然后父函数可以传入一个命令,并可选择开始它自己的事务块,否则,将由被调用的函数创建并提交一个。