C# “SqlConnection 不支持并行事务”什么时候发生?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19559715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:17:39  来源:igfitidea点击:

When does "SqlConnection does not support parallel transactions" happen?

c#.nettransactionssqlconnection

提问by sharptooth

I have a ton of rather working code that's been here for months and today I saw the following exception logged:

我有很多相当有效的代码已经在这里好几个月了,今天我看到记录了以下异常:

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

and I'd like to investigate why this exception was thrown. I've read MSDN description of BeginTransaction()and all it says is that well, sometimes this exception can be thrown.

我想调查为什么会抛出这个异常。我已经阅读了 MSDN 的描述,BeginTransaction()它说的很好,有时会抛出这个异常。

What does this exception mean exactly? What is the deficiency in my code that I should be looking for?

这个异常究竟是什么意思?我应该寻找的代码中的哪些缺陷?

采纳答案by SimonGoldstone

You'll get this if the connection already has an uncommitted transaction and you call BeginTransaction again.

如果连接已经有一个未提交的事务并且您再次调用 BeginTransaction,您将得到此信息。

In this example:

在这个例子中:

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

... I get exactly the same exception at the second BeginTransaction.

...我在第二个 BeginTransaction 中得到完全相同的异常。

Make sure the first transaction is committed or rolled back before the next one.

确保第一个事务在下一个事务之前提交或回滚。

If you want nested transactions, you might find TransactionScopeis the way forward.

如果您想要嵌套事务,您可能会发现TransactionScope是前进的方向。

回答by Silvermind

The same problem occurs when using the 'wrong' method for a transaction, this happened after we upgraded to a newer version of the Entity Framework.

对事务使用“错误”方法时会出现同样的问题,这是在我们升级到较新版本的实体框架之后发生的。

In the past we were using the following method to create a transaction and mixed EF strong typed linq queries with Sql queries, but since the Connectionproperty did not exist anymore, we replaced all db.with db.Database, which was wrong:

过去我们使用下面的方法来创建一个事务,将 EF 强类型 linq 查询与 Sql 查询混合,但由于该Connection属性不再存在,我们将全部替换db.db.Database,这是错误的:

// 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
}

Somewhere they changed the behaviour of that transaction method behaviour with a newer version of the Entity Framework and the solution is to use:

在某个地方,他们使用较新版本的实体框架更改了该事务方法行为的行为,解决方案是使用:

db.Database.Connection.Open();
using (var transaction = db.Database.BeginTransaction())
{
    // do stuff inside transaction
}

Notice that the transaction is now callen on Databaseinstead of Connection.

请注意,事务现在被调用Database而不是Connection