【问题标题】:When does "SqlConnection does not support parallel transactions" happen?“SqlConnection 不支持并行事务”什么时候发生?
【发布时间】:2013-10-24 07:34:03
【问题描述】:

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

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 描述,它只是说,有时会抛出这个异常。

这个异常到底是什么意思?我应该在我的代码中寻找什么缺陷?

【问题讨论】:

  • 您是在使用常规的 SqlConnection/SqlCommmand/SqlDataAdapter 还是在使用 ORM(例如 EF 或 L2S 或其他)?代码是使用显式事务还是 TransactionScopes?另外,您能否围绕正在记录/引发异常的错误发布代码示例?
  • 查看这个答案:stackoverflow.com/questions/407320/… 是差不多的问题。
  • @SimonGoldstone:如果我可以缩小问题范围,我不会问这个问题。我不是在问“我的代码不起作用,请尽快提供帮助”,我是在问我必须在我的代码中寻找什么。
  • 所以为了缩小问题的范围,您是使用常规的SqlConnection/SqlCommmand/SqlDataAdapter 还是使用 ORM(例如 EF 或 L2S 或其他)?代码是使用显式事务还是 TransactionScopes?
  • @SimonGoldstone:代码使用SQL???无需任何中间件,直接使用 SqlTransaction 进行交易。

标签: c# .net transactions sqlconnection


【解决方案1】:

如果连接已经有一个未提交的事务并且你再次调用 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 是前进的方向。

【讨论】:

    【解决方案2】:

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

    过去我们使用下面的方法来创建事务和混合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
    }
    

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

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

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

    【讨论】:

    • 这个解决方案解决了我的问题,因为我使用的是 EF 数据库第一个模型,并且我使用“非事务连接”来执行对事务中其他表的查询。
    • 我发现 TransactionScope 在 EF 中也能很好地工作。我已经很久没有使用 BeginTransaction 了。几乎我所有的事务工作都是在 TransactopScopes 内完成的。
    • 感谢您发布此信息。我有完全相同的问题。 +1,即使它不是 OP 特定情况的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    相关资源
    最近更新 更多