2010-12-14 73 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语句。

相关问题