如何解决在 foreach 循环内回滚或提交事务
我在 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();
}
}
}
这里的问题是,当我在错误迭代之后进行成功迭代时,错误迭代的更改(称为回滚)仍然会被保存。
解决方法
您修改的实体仍由上下文跟踪,因此更改将在下一次 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
。另请注意,如果有两个对象,重新创建上下文可能是更好的选择(或者您只能在上次运行出错的情况下重新创建它)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。