2013-10-24 97 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

相關問題