How to nest transactions in EF Core 6?(如何在EF Core6中嵌套事务?)
问题描述
在某些情况下,我已经在存储库函数中使用事务,因为我有时需要一次将数据插入两个表,并且如果其中一个插入失败,我希望整个操作失败。
现在我遇到了这样一种情况:我必须将对多个存储库/函数的调用包装在另一个事务中,但是当其中一个函数已经在内部使用事务时,我将收到错误The connection is already in a transaction and cannot participate in another transaction
。我不想从存储库功能中删除事务,因为这意味着我必须知道事务需要哪些存储库功能,然后我必须在服务层中实现这些功能。另一方面,我似乎不能在事务中使用存储库函数,因为它们已经在内部使用了事务。以下是我面临此问题的一个示例:
// Reverse engineered classes
public partial class TblProject
{
public TblProject()
{
TblProjectStepSequences = new HashSet<TblProjectStepSequence>();
}
public int ProjectId { get; set; }
public virtual ICollection<TblProjectStepSequence> TblProjectStepSequences { get; set; }
}
public partial class TblProjectTranslation
{
public int ProjectId { get; set; }
public string Language { get; set; }
public string ProjectName { get; set; }
public virtual TblProject Project { get; set; }
}
public partial class TblProjectStepSequence
{
public int SequenceId { get; set; }
public int ProjectId { get; set; }
public int StepId { get; set; }
public int SequencePosition { get; set; }
public virtual TblStep Step { get; set; }
public virtual TblProject Project { get; set; }
}
// Creating a project in the ProjectRepository
public async Task<int> CreateProjectAsync(TblProject project, ...)
{
using (var transaction = this.Context.Database.BeginTransaction())
{
await this.Context.TblProjects.AddAsync(project);
await this.Context.SaveChangesAsync();
// Insert translations... (project Id is required for this)
await this.Context.SaveChangesAsync();
transaction.Commit();
return entity.ProjectId;
}
}
// Creating the steps for a project in the StepRepository
public async Task<IEnumerable<int>> CreateProjectStepsAsync(int projectId, IEnumerable<TblProjectStepSequence> steps)
{
await this.Context.TblProjectStepSequences.AddRangeAsync(steps);
await this.Context.SaveChangesAsync();
return steps.Select(step =>
{
return step.SequenceId;
}
);
}
// Creating a project with its steps in the service layer
public async Task<int> CreateProjectWithStepsAsync(TblProject project, IEnumerable<TblProjectStepSequence> steps)
{
// This is basically a wrapper around Database.BeginTransaction() and IDbContextTransaction
using (Transaction transaction = await transactionService.BeginTransactionAsync())
{
int projectId = await projectRepository.CreateProjectAsync(project);
await stepRepository.CreateProjectStepsAsync(projectId, steps);
return projectId;
}
}
有没有办法在不知道内部事务中可能存在外部事务的情况下,将多个事务嵌套在彼此内部?我知道从技术角度来看,可能无法实际嵌套这些事务,但我仍然需要一个解决方案,该解决方案要么使用存储库的内部事务,要么使用外部事务(如果存在),因此我不可能意外地忘记将事务用于需要事务的存储库功能。
推荐答案
您可以检查CurrentTransaction属性并执行如下操作:
var transaction = Database.CurrentTransaction ?? Database.BeginTransaction()
如果已存在使用该事务的事务,则启动一个新事务.
编辑:删除了使用挡路的,请参阅评论。提交/回滚超越需要更多逻辑.
这篇关于如何在EF Core6中嵌套事务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在EF Core6中嵌套事务?
基础教程推荐
- 如何激活MC67中的红灯 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01