2013-12-09 55 views
2

我在實體框架中爲兩個不同的數據庫創建了兩個不同的上下文。現在我試圖在單個事務中更新這些數據庫。我的代碼是這樣的:實體框架中的一個事務中的多個數據庫

public class LPO_BLL 
{ 
    internal Context1 _context1 = null; 
    internal Context2 _Context2 = null; 

    public LPO_Detail_BLL(Context1 context1, Context2 context2) 
    { 
     _context1 = context1; 
     _context2 = context2; 
    } 

    public void Insert(PM_LPO lpo, LPO_Transaction lpo_transaction) 
    { 
     using (TransactionScope transaction = new TransactionScope()) 
     { 
      _context1.LPO.Add(lpo); 
      _context1.SaveChanges(); 

      _context2.LPO_Transaction.Add(lpo_transaction); 
      _context2.SaveChanges(); // I am getting error here... 

      transaction.Complete(); 
     } 
    } 
} 

而且在UI項目,我調用此爲:

LPO lpo = new LPO(); 
//setting properties of lpo 

LPO_Transaction lpo_trans = new LPO_Transaction(); 
//setting properties of lpo_trans 

Context1 _context1 = new Context1(); 
//Opening _context1 connection and etc 

Context2 _context2 = new Context2(); 
//Opening _context2 connection and etc 

LPO_BLL lpo_bll = new LPO_BLL(_context1, _context2); 

lpo_bll.Insert(lpo,lpo_trans); 

目前,我得到錯誤: 基礎提供失敗的EnlistTransaction

經過最近3小時在互聯網上搜索並嘗試不同的命中和試用方法後,我決定把它放在SO上。到目前爲止,我發現這兩個環節來有點接近:

http://social.msdn.microsoft.com/Forums/en-US/3ccac6f7-6513-4c87-828a-00e0b88285bc/the-underlying-provider-failed-on-enlisttransaction?forum=adodotnetentityframework

TransactionScope - The underlying provider failed on EnlistTransaction. MSDTC being aborted

回答

2

並不是所有DB提供程序支持分佈式事務。

使用事務範圍將嘗試在由MSDTC管理的分佈式事務中登記數據庫事務。如果你的提供者不支持這個,它會失敗。

SQL Server和Oracle提供程序支持分佈式事務。但許多其他EF提供商不這樣做。

如果您的數據庫提供商不支持此操作,則必須使用其他數據庫或放棄使用事務。

你使用SQL Server 2005提供的,它應該是工作,但是:

看。

注意:該服務的名稱是MSDTC。所以你可以運行net start msdtcnet stop msdtc。如果您在控制面板中查找它,您會發現一個描述性名稱,如「分佈式事務處理協調器」或本地化名稱,如「Coordinador de transacciones distribuidas」。奇怪的是,沒有辦法在本地服務的控制面板列表中顯示名稱列。

+0

我使用SQL Server作爲兩種上下文的提供者。 –

+0

MSDTC是否正在運行?你是如何創建連接字符串的? – JotaBe

+0

我在Application_Start事件中的Global.ascx中創建連接字符串。我不知道MSDTC是否在運行? –

1

應使用Savechange(false)和AcceptAllChanges()的多個數據庫集。

public void Insert(PM_LPO lpo, LPO_Transaction lpo_transaction) 
{ 
    using (TransactionScope transaction = new TransactionScope()) 
    { 

     context1.SaveChanges(false); 
     context2.SaveChanges(false); 

     _context1.LPO.Add(lpo); 
     _context2.LPO_Transaction.Add(lpo_transaction);  

     transaction.Complete(); 

     context1.AcceptAllChanges(); 
     context2.AcceptAllChanges(); 

    } 
} 
+0

我正在使用Entity Framework 5,並且沒有接受任何參數的SaveChanges方法。 –

+0

usman可能是你找到這個有用的http://blogs.msdn.com/b/alexj/archive/2009/01/11/savechanges-false.aspx – YOusaFZai

+0

這是很好的方法,但我不知道爲什麼SaveChanges(false)在我的應用程序中不受支持。我正在使用實體框架5. –

1

你必須使用ObjectContext的在你的DbContext才能使用的SaveChanges與參數:

public class EntityDBContext: DbContext, IObjectContextAdapter 
{ 
    ObjectContext IObjectContextAdapter.ObjectContext { 
     get { 
      return (this as IObjectContextAdapter).ObjectContext; 
     } 
    } 
} 

,然後在你的插入方法,使用:

public void Insert(PM_LPO lpo, LPO_Transaction lpo_transaction) 
{ 
    using (TransactionScope transaction = new TransactionScope()) 
    { 

     context1.ObjectContext.SaveChanges(false); 
     context2.ObjectContext.SaveChanges(false); 

     _context1.LPO.Add(lpo); 
     _context2.LPO_Transaction.Add(lpo_transaction);  

     transaction.Complete(); 

     context1.ObjectContext.AcceptAllChanges(); 
     context2.ObjectContext.AcceptAllChanges(); 

    } 
} 
相關問題