【问题标题】:Overriding SaveChangesAsync when enclosed inside TransactionScope?包含在 TransactionScope 中时覆盖 SaveChangesAsync?
【发布时间】:2017-07-31 10:54:18
【问题描述】:

我对 EF 事务还很陌生,这是用于保存的代码

public bool Save(TbArea area, bool isNew, out string errMsg)
        {
            try
            {
                errMsg = string.Empty;
    using (var oScope = new System.Transactions.TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(120)))
                    {
                        try
                        {
                            TbArea oEntity = oContext.TbArea.Where(a => a.AreaCode == area.AreaCode && a.CompanyId == MainClass.SystemCompanyId).FirstOrDefault();
                            if (oEntity != null)
                            {
                                if (isNew) { errMsg = Resources.ResSales.MsgRecordCodeDublicated; return false; }
                                oContext.TbArea.Attach(oEntity);
                                oContext.Entry(oEntity).CurrentValues.SetValues(area);
                            }
                            else
                            {
                                if (!isNew) { errMsg = Resources.ResSales.MsgRecordNotFoundInDB; return false; }
                                oContext.TbArea.Add(area);
                            }

                            oContext.SaveChangesAsync();
                            oScope.Complete();
                            return true;
                        }
                        catch (Exception ex)
                        {
                            oScope.Dispose();
                            errMsg = ex.Message;
                            return false;
                        }
                    }

我正在覆盖SaveChangesAsync 这样我就可以将ChangeTracker.Entries 保存到数据库中。 这是代码的一部分:

    dbContext.AcceptAllChanges();
    logsSet.AddRange(audits);
    int result = 0;
    try
      {
         result = await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
                //scope.Complete(); there was a transaction that I commented out, I thought it might overlaps the original transaction!

          return result;
       }
     catch (Exception ex)
          {
             var m = ex.Message;
             return result;
          }

当我保存一个项目时,我得到了错误:

事务已中止

当我删除事务范围时,保存会正常进行!

【问题讨论】:

  • 为什么要提到时间戳??这是日志运行操作吗??
  • 不,我删除了它仍然得到同样的错误
  • 我将 TransactionScope 移到了被覆盖的方法中,它现在可以工作了
  • 虽然可能在您的 MVCE 中省略,但请注意 SaveAllChanges 是在(单阶段)事务下完成的。只有在需要其他活动时才需要 TransactionScope。此外,不需要异常处理程序中的显式 oscope.Dispose - 它已经包含在使用块的包装中。

标签: c# entity-framework transactionscope


【解决方案1】:

您的代码在更改完成保存之前将事务标记为完成:

oContext.SaveChangesAsync();
oScope.Complete();

你需要使用await:

await oContext.SaveChangesAsync();
oScope.Complete();

如果您处于await 可以在不同线程上恢复的上下文中,您可能还需要指定TransactionScopeAsyncFlowOption.Enabled

【讨论】:

  • 问题是这个方法把out string作为参数所以我不能标记它async
  • 然后更改您的返回类型以包含所有out 参数。
猜你喜欢
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多