2009-04-27 85 views
24

請參閱下面的代碼。如果我初始化多個實體上下文,那麼我在第二組代碼上得到以下例外。如果我註釋掉第二組,它就可以工作。爲什麼TransactionScope不能與實體框架一起使用?

{ 「底層提供對打開失敗。」}

內:{ 「與基礎事務管理器通信失敗。」}

內:{「錯誤HRESULT E_FAIL已退還從一個COM組件調用。「}

請注意,這是一個示例應用程序,我知道它沒有意義在一行中創建2個上下文。但是,生產代碼確實有理由在同一個TransactionScope中創建多個上下文,並且這是不能更改的。

編輯

這裏是我試圖建立MS-DTC前一個問題。它似乎在服務器和客戶端都啓用。我不確定它是否設置正確。另外請注意,我試圖這樣做的原因之一是TransactionScope中的現有代碼使用ADO.NET和Linq 2 Sql ...我希望那些也使用相同的事務。 (這可能聽起來很瘋狂,但如果可能的話我需要使它工作)。

How do I use TransactionScope in C#?

Windows防火牆擋住到MS-DTC的連接。

using(TransactionScope ts = new System.Transactions.TransactionScope()) 
     { 
       using (DatabaseEntityModel o = new DatabaseEntityModel()) 
       { 
        var v = (from s in o.Advertiser select s).First(); 
        v.AcceptableLength = 1; 
        o.SaveChanges(); 
       } 

       //-> By commenting out this section, it works 
       using (DatabaseEntityModel o = new DatabaseEntityModel()) 
       { 
        //Exception on this next line 
        var v = (from s1 in o.Advertiser select s1).First();       v.AcceptableLength = 1; 
        o.SaveChanges(); 
       } 
       //-> 

       ts.Complete(); 
     } 

回答

18

您的MS-DTC(分佈式事務協調器)出於某種原因無法正常工作。 MS-DTC用於協調跨多種異構資源(包括多個sql連接)的事務結果。

查看this link以瞭解正在發生的更多信息。

基本上,如果你確定你的MS-DTC正在運行並正常工作,你應該沒有使用2個ADO.NET連接的問題 - 無論它們是實體框架連接還是任何其他類型。

19

可避免管理自己的EntityConnection,並把該EntityConnection到您的ObjectContext使用分佈式事務。否則,檢查這些。

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=580828&SiteID=1&mode=1 http://forums.microsoft.com/msdn/showpost.aspx?postid=113669&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1

EntityConnection conn = new EntityConnection(ConnectionString); 

using (TransactionScope ts = new TransactionScope()) 
{ 
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn)) 
    { 
      var v = (from s in o.Advertiser select s).First(); 
      v.AcceptableLength = 1; 
    } 

    //-> By commenting out this section, it works 
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn)) 
    { 
     //Exception on this next line 
     var v = (from s1 in o.Advertiser select s1).First(); 
       v.AcceptableLength = 1; 
    } 
    //-> 

    ts.Complete(); 
} 
+0

我不只是使用實體框架,因此重複使用EntityConnection也不是一個簡單的解決方案(請參閱上面的編輯) – NotDan 2009-04-27 19:01:07

+6

+1用於避免DTC。這並不是壞事,只是分佈式交易不是輕易選擇的東西。這是應用程序和資源的緊密鏈接,可能會降低設計的可用性。 – 2009-04-27 19:48:43

+0

您也可以調用context.Connection.Open()手動管理它。你不需要手動創建EntityConnection – 2009-12-24 16:41:23

1

的問題是,2種不同的DataContext有效地創建兩個不同的連接。

在這種情況下,事務HAS被提升爲分佈式事務。我假設你的問題來自服務器和客戶端上MS DTC(Microsoft分佈式事務處理協調器)的配置。 例如,如果服務器未配置爲允許MSDTC的遠程連接,則會遇到此類異常。

例如,您可以參考this MS page來排除MSDTC問題,並且Google會向文章/論壇提問。

現在,它可能是別的,但它聽起來像是一個MSDTC問題。

3

BTW你應該考慮結合使用的SaveChanges(假)用的AcceptChanges在使用你喜歡這個明確的交易()。如果

這樣東西的SaveChanges(假)失敗,則ObjectContext的還沒有放棄你的更改,以便以後可以重新申請或者做一些錯誤記錄等

看到這個職位的詳細資料:http://blogs.msdn.com/alexj/archive/2009/01/11/savechanges-false.aspx

乾杯

亞歷

5

添加C:\ WINDOWS \ msdtc.exe到防火牆和服務器上的防火牆例外。我花了很多時間在開放特定的端口號碼和範圍之前瞎搞,在我這樣做之前無濟於事。

0

從MQ隊列中讀取消息,處理它們並存儲在SQL 2005 Express Edition數據庫中時,使用DTC時發生過類似的錯誤。我沒有足夠的時間來調查2005年底或者令人興奮的Express版造成這個問題,但切換到2008年Standard將這種特殊行爲淡化了出來。

4

我打算在這裏堅持下去,因爲昨天我和同事一起花了3個小時來調試這個問題。圍繞這個問題的每一個答案都表明,這總是一個防火牆問題。但在我們的情況下,它不是。希望這會使其他人免於痛苦。

我們的情況是,我們目前正在遷移到實體框架。這意味着我們有部分代碼在單個事務連接內部直接使用new SqlConnection(connectionString).Open()打開,並通過使用EF數據上下文間接打開。

這在我們的應用程序中一直運行良好,但是當我們開始回溯並將測試放在生產中的代碼周圍時,從測試運行器執行的代碼不斷在第一次EF對象在之後試圖連接到數據庫在同一事務中已經進行了直接連接。

錯誤的原因最終證明是,如果您沒有爲連接字符串提供參數Application Name=,實體框架會默認添加一個參數(如EntityFrameworkMUF)。這意味着你必須在你的連接池兩個不同的連接方式:

  1. ,你有沒有Application Name=參數
  2. 自動生成一個後綴Application Name=EntityFrameworkMUF

,這是不可能的手動打開一個在單個事務中打開兩個不同的連接。生產代碼指定了一個應用程序名稱;因此它工作;測試代碼沒有。指定Application Name=參數爲我們修復了這個錯誤。

相關問題