2011-02-10 36 views
4

我有以下情形:LINQ到SQL的TransactionScope

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },EnterpriseServicesInteropOption.Automatic)) 
{ 
    using (DataContext db = new DataContext()) 
    { 
    db.Connection.Open(); 
    db.Transaction = db.Connection.BeginTransaction(); 
    try 
    { 
     bool outcome = InvokeInTransaction<string, object>(inputDict, out outputDict); 
     db.Transaction.Commit(); 
    } 
    catch (Exception ex) 
    { 
     response.Outcome = BusinessEntityResponse.SystemError; 
     db.Transaction.Rollback(); 
    } 
    } 
} 

裏面的InvokeInTransaction電話是一個數字,一個LTS資源庫做了進行各種數據的變化呼叫。問題是在倉庫裏面還有另一個

using (var db = new DataContext()) 

裏面是持久性代碼。檢查存儲庫中的上下文顯示Transaction = null,並且我懷疑「內部」上下文不知道Ambient事務。這可以做到嗎?據我所知,EF在此基礎上進行了管理,並且約束條件是存儲庫代碼無法更改。任何幫助?

回答

5

我們使用LinqToSql和TransactionScope進行多個數據庫事務。如果你打算嘗試它,你應該真正控制你的連接/上下文/事務生命週期。

  • 我們通過規則來控制DataContext實例:如果你新建了一個,你可以使用using語句來實現。
  • 我們通過規則控制連接生命週期:如果打開它,則必須關閉它(但通常讓DataContext實例管理它)。
  • 我們通過該規則控制事務生命週期:讓DataContext管理SubmitChanges中發生的事情,讓TransactionScope管理在其使用塊內發生的事情。

下面是一個代碼示例:

using (OuterDataContext outerDataContext = GetOuterDataContext()) 
{ 
    using (InnerDataContext innerDataContext = GetInnerDataContext()) 
    { 
    try 
    { 
     OuterRepository outerRepository = new OuterRepository(); 
     // may read records into memory for updating/deleting. 
     outerRepository.WorkWithOuterRecords(outerRecords, outerDataContext); 

     InnerRepository innerRepository = new InnerRepository(); 
     // may read records into memory for updating/deleting. 
     innerRepository.WorkWithInnerRecords(innerRecords, innerDataContext); 

     using (TransactionScope scope = new TransactionScope()) 
     { 
      //starts a local tranaction in outerDB, held open by scope 
     outerDataContext.SubmitChanges(); 
      //promotes the transaction to distributed, still held open by scope 
     innerDataContext.SubmitChanges(); 
      // and done 
     scope.Complete(); 
     } 
    } 
    catch (Exception ex) 
    { 
     LoggerClient.Log(ex); 
     response.Message = "It didn't save anything."; 
    } 
    } 
} 
+0

感謝大衛,這種模式肯定是看起來很好的實現,我喜歡WorkWith *記錄爲保持上下文範圍的手段,我只是我沒能得到圍繞着我的棕色領域的存儲庫類實現(對這些類的調用者進行過多的重構)。因此原來的問題。不錯的圖案雖然.. – OldBoy 2011-02-12 13:39:33