2010-12-14 89 views
1

我的應用程序(WCF服務)使用LINQ數據上下文,最近我們決定將所有內容都包含在事務中。似乎工作得很好;對服務的每次調用都有自己的事務,因此如果拋出異常,則所有事件都會回滾並且不會向數據庫提交任何更改。嘗試創建/使用內部事務時出現異常

但是,我們有一個「管理者代碼」,它可以產生和一次只用了一個概念。我們希望即使在操作稍後發生錯誤,管理員代碼也會被標記爲正在使用。對我而言,這表明我應該使用內部交易?

所以我SetToUsed方法裏面,我把一個新的事務,像這樣:

public void SetToUsed(string code) 
    { 
     // security codes explicitly need their own transaction so that they will still be marked as having been used even if the outer transaction were to be rolled back due to error 
     using (var securityCodeTransaction = new TransactionScope(
       TransactionScopeOption.RequiresNew, 
       new TransactionOptions 
       { 
        IsolationLevel = IsolationLevel.ReadUncommitted 
       }, 
       EnterpriseServicesInteropOption.Automatic)) 
     { 
      var returnedItems = m_safetyCodeRepository.FindAll(sc => sc.safetyCode == code && 
                    sc.safetyCodeTypeId == (long)GetCodeType() && 
                    sc.isUsed == false); 
      foreach (var item in returnedItems) 
      { 
       item.isUsed = true; 
       m_safetyCodeRepository.SaveChanges(item); 
      } 

      securityCodeTransaction.Complete(); 
     } 
    } 

然而,這會導致異常:System.InvalidOperationException: Connection currently has transaction enlisted. Finish current transaction and retry.
拋出異常的FindAll線,這是一個瘦包裝對於

dataContext.GetTable<tbSftSafetyCodes>().Where(exp).ToList() 

我是否錯過了某些東西,或者完全以錯誤的方式解決這個問題?

編輯:我意識到,我並不真的需要一個交易爲管理代碼的變化本身。
所以我改爲TransactionScopeOption改爲TransactionScopeOption.Suppress。我仍然想知道爲什麼使用TransactionScopeOption.RequiresNew的內部交易不起作用!

+0

如何創建外部事務(如果有)? – 2010-12-14 06:21:38

+0

@Mark:外部的TransactionScope以相同的方式創建,在堆棧中更高。 – Coxy 2010-12-15 02:51:47

回答

4
TransactionScopeOption.RequiresNew  

嘗試啓動一個全新的事務,而這個事務獨立於它所處的那個事務,這是你的意圖嗎? 「需求」選項會將新事務添加到當前活動的事務中。

然而,如果yopu總是希望所使用的被標記的代碼 - 你需要把它在一個事務中呢?你能不能把它標記爲剛剛開始你的事務處理包裝操作之前使用的amd commit?

+0

是的,意圖是讓內部事務完全獨立於外部事務,所以即使外部事務失敗,它也會始終提交。我們正在嵌套事務,因爲我們將事務性添加到現有應用程序以及它如何適應當前體系結構。 – Coxy 2010-12-15 02:53:44

0

在使用選項TransactionScopeOption.RequiresNew它也是必要的

dc.Connection.Open(); 
    dc.Connection.EnlistTransaction(Transaction.Current); 
    if (dc.Connection.State!=ConnectionState.Closed) dc.Connection.Close(); 

    using (var securityCodeTransaction = new TransactionScope(
      TransactionScopeOption.RequiresNew, 
      new TransactionOptions 
      { 
       IsolationLevel = IsolationLevel.ReadUncommitted 
      }, 
      EnterpriseServicesInteropOption.Automatic)) 
    { 
      // same code as in question 
    } 

這讓問題消失於preceed using語句旁邊我的情況 - 但是,我不知道爲什麼要求。

注意:爲了登記交易,連接必須是開放的 - 因此需要open + close語句。

相關問題