尝试 开始事务,保存更改 捕获 回滚,开始另一个事务,保存更改 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 核心的主要内容,如果未能解决你的问题,请参考以下文章