gpt4 book ai didi

c# - 如何在 EF Core 6 中嵌套事务?

转载 作者:行者123 更新时间:2023-12-05 08:03:55 24 4
gpt4 key购买 nike

在某些情况下,我已经在我的存储库函数中使用了事务,因为我有时需要同时将数据插入到两个表中,如果其中一个插入失败,我希望整个操作失败。

现在我遇到了这样一种情况,我不得不在另一个事务中包装对多个存储库/函数的调用,但是当其中一个函数已经在内部使用一个事务时,我将得到错误 The connection is already in a 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()

如果已经有一个事务使用那个,否则开始一个新的...

编辑:删除了 Using block ,请参阅评论。尽管提交/回滚事务需要更多逻辑......

关于c# - 如何在 EF Core 6 中嵌套事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70958670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com