【问题标题】:Rollback or commit Transactions inside a foreach loop在 foreach 循环中回滚或提交事务
【发布时间】:2021-01-10 09:47:13
【问题描述】:

我在 MVC 应用程序中使用 Entity Framework 6 和 .Net Framework 4.8。我正在尝试对实体列表(发票)做两件事:

  • 生成电子邮件并发送。
  • 更新实体并保存。

当电子邮件发送失败时,我想回滚我对实体所做的所有更改。

这是我的代码:

foreach (var id in listOfIds)
{
  using (var dbContextTransaction = db.Database.BeginTransaction())
  {
    try 
    {
      var invoice = db.Invoices.Find(id);
      MakeChangesToInvoice(invoice);
      var pdf = GeneratePdf(invoice);
      SendEmail(pdf);
      db.SaveChanges();
      dbContextTransaction.Commit();
    }
    catch(SomeEmailException)
    {
      dbContextTransaction.Rollback();
    }
  }
}

这里的问题是,当我在错误迭代之后成功完成迭代时,错误迭代(称为回滚)的更改仍然会被保存。

【问题讨论】:

  • 为什么要使用Transaction?如果您想在成功发送电子邮件后保存数据并在失败后跳过保存,看起来只使用 db.SaveChanges() 就足够了。
  • 更新了我的答案。在发送电子邮件之前对实体进行了更改,因为我需要这些更改来创建 PDF。仅供参考:我的代码比我发布的示例复杂得多,但细节可能会使问题不太清楚。如果您需要更多详细信息,请告诉我。
  • dbContextTransaction.Rollback() 仅回滚 db 更改,您对实体的更改仍然存在,我在 Entity Framework 中不太好,因为我使用 Entity Framework Core,但我认为您在某些实体中的更改存在并跟踪所以下一个 db.SaveChanges() 和 Commit 只是保存它。要获得更准确的答案,最好看看你在你的隐形代码中做了什么。
  • 您真的,真的应该在事务中进行扩展处理。

标签: c# entity-framework transactions entity-framework-6


【解决方案1】:

您已修改的实体仍由上下文跟踪,因此更改将在下一次 SaveChanges 调用(在下一次迭代中)传播到数据库,因此您需要重新创建您的 dbcontext(可能有对性能的显着影响,需要检查)每次迭代或分离实体。像这样的:

Invoice invoice = null;
try 
{
  invoice = db.Invoices.Find(id);
  MakeChangesToInvoice(invoice);
  var pdf = GeneratePdf(invoice);
  SendEmail(pdf);
  db.SaveChanges();
  dbContextTransaction.Commit();
}
catch(SomeEmailException)
{
  dbContextTransaction.Rollback();
  // note that if you have complex object graph this possibly will not detach child objects 
  if(invoice != null) dbContext.Entry(invoice).State = EntityState.Detached;
}

如果合适的话,或者使用this answer 中的DetachAll。另请注意,如果有两个对象,则重新创建上下文可能是更好的选择(或者您可以仅在上一次运行出错的情况下重新创建它)。

【讨论】:

  • 太棒了!受您的回答启发,我发现了这个:stackoverflow.com/a/17967959/448355。我现在正在使用它(创建很多子对象并更改关系对象)并且效果很好。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 2012-12-24
  • 2013-11-20
  • 2013-11-22
相关资源
最近更新 更多