2013-10-24 60 views
21

我有一吨重的是一直在这里几个月,而今天工作的代码,我看到了下面的异常记录:什么时候发生“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描述,并且它说的很好,有时可能会引发此异常。

这个例外意味着什么?我应该寻找的代码有哪些缺陷?

+0

您是否使用普通的SqlConnection/SqlCommmand/SqlDataAdapter或者您使用的是ORM(例如EF或L2S或其他)?并且是使用显式事务或TransactionScopes的代码?另外,您是否可以在记录/抛出异常的错误周围发布代码示例? – SimonGoldstone

+0

检查这个答案:http://stackoverflow.com/questions/407320/strange-sql2005-problem-sqlconnection-does-not-support-parallel-transactions 这是关于同样的问题。 – LawfulHacker

+0

@SimonGoldstone:如果我能缩小问题范围,我不会问这个问题。我并不是问“我的代码无法正常工作,请尽快帮忙”,我问我需要在代码中寻找什么。 – sharptooth

回答

17

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

10

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

在过去,我们用下面的方法来创建一个事务,并与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 
} 

某处他们改变与实体框架和新版本的解决方案,交易方法的行为的行为是使用:

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

注意?该交易现在在Database上进行,而不是Connection

+0

这个解决方案解决了我的问题,因为我使用EF数据库第一个模型,并且我使用“非事务连接”来执行对事务内其他表的查询。 –

+0

我发现TransactionScope在EF内部工作得很好。我现在还没有用过BeginTransaction。几乎所有的交易工作都在TransactopScopes内完成。 – SimonGoldstone

+4

感谢您发布此信息。我有完全相同的问题。 +1,尽管这不是OP特殊情况的答案。 – Raithlin

相关问题