尝试 开始事务,保存更改 捕获 回滚,开始另一个事务,保存更改 EF 核心

Posted

技术标签:

【中文标题】尝试 开始事务,保存更改 捕获 回滚,开始另一个事务,保存更改 EF 核心【英文标题】:try begin transaction, savechanges catch rollback, begin another transaction, savechanges EF core尝试 开始事务,保存更改 捕获 回滚,开始另一个事务,保存更改 EF 核心 【发布时间】:2021-07-08 09:20:50 【问题描述】:

我有一个名为_context 的数据库,我想在名为“workers”的表中插入一些“worker”。帮助我实现这一目标的功能是使用后台服务库每两个小时运行一次。我需要记录发生错误时发生的情况,因此我设置了一个名为“Log”的表,该表将填写每个错误或成功。

所以我试试:

IDbContextTransaction transac = null;
try

   //...
   //code here with _context.workers.toListAsync() etc..
   //...

   foreach (var worker in WorkerList)
   
      transac = _context.Database.BeginTransaction();
      _context.workers.Add(worker);

      await _context.SaveChangesAsync();
      transac.Commit();

      //LogSuccess
      Log logSuccess = "Worker successfully added";

      _context.Log.Add(logSuccess);
      await _context.SaveChangesAsync();  
   

catch(Exception ex)

   transac.Rollback();

   //LogErreur
   Log logError = ex.message;

   transac = _context.Database.BeginTransaction();
   _context.Log.Add(logError);
   await _context.SaveChangesAsync();

我的问题如下:

_context.SaveChangesAsync() 发生错误时(在添加worker 之后),它进入catch 并开始另一个事务。但是当_context.SaveChangesAsync 出现时,程序会抛出与之前第一个_context.SaveChangesAsync() 相同的错误。对我来说,transac.rollback() 应该“删除”之前的交易。

【问题讨论】:

我想说,每次迭代都使用一个新的上下文实例,不要启动事务,而只使用一个 SaveChanges 调用,因为这已经是事务性的。在catch 中使用新的上下文实例进行日志记录。 【参考方案1】:

SaveChanges 中的失败不会清除更改跟踪器,因此随后调用 SaveChanges 将尝试再次保存所有更改。这使您能够重试暂时性错误或在重试之前修改挂起的更改。

要么使用新的 DbContext,要么调用 ChangeTracker.Clear。

【讨论】:

以上是关于尝试 开始事务,保存更改 捕获 回滚,开始另一个事务,保存更改 EF 核心的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务异常回滚,捕获异常不抛出就不会回滚

Spring事务异常回滚,捕获异常不抛出就不会回滚

spring事务没回滚

Postgresql 捕获事务错误和回滚

Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题

SQL记录-PLSQL事务