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

时间:2013-10-24 07:34:04

标签: c# .net transactions sqlconnection

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

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

我想调查抛出此异常的原因。我已经阅读了BeginTransaction()的MSDN描述,并且它说的很好,有时可以抛出此异常。

这个例外究竟意味着什么?我应该寻找的代码缺点是什么?

2 个答案:

答案 0 :(得分:19)

如果连接已经有一个未提交的事务并且你再次调用BeginTransaction,你就会得到这个。

在这个例子中:

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

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

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

如果您想要嵌套交易,您可能会发现TransactionScope是前进之路。

答案 1 :(得分:11)

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

过去我们使用以下方法创建事务并使用Sql查询混合EF强类型linq查询,但由于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
}

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

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

请注意,该交易现在已在Database而非Connection上进行了广告。