【问题标题】: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 中使用新的上下文实例进行日志记录。

标签: c# entity-framework transactions dbcontext rollback


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    相关资源
    最近更新 更多