C# EF Core和Postgres中的原子事务
我有一个Postgres数据库,里面装满了任务,还有一个程序可以检索和处理任务。 现在我用这种方式检索:C# EF Core和Postgres中的原子事务,c#,postgresql,transactions,entity-framework-core,C#,Postgresql,Transactions,Entity Framework Core,我有一个Postgres数据库,里面装满了任务,还有一个程序可以检索和处理任务。 现在我用这种方式检索: var tasks = await _context.Tasks .Where(t => t.status== Status.New) .OrderBy(t => t.StartTime) .Tak
var tasks = await _context.Tasks
.Where(t => t.status== Status.New)
.OrderBy(t => t.StartTime)
.Take(maxAmount)
.ToListAsync();
tasks.ForEach((t) => t.status= Status.Launched);
await _context.SaveChangesAsync();
现在我想让它能够并行运行,首先在多个线程中运行,然后在不同的机器上运行多个实例。
我尝试的是使用如下事务:
var strategy = _context.Database.CreateExecutionStrategy();
return await strategy.ExecuteAsync(async () =>
{
using var transaction = _context.Database.BeginTransaction();
try
{
var tasks = await _context.Tasks
.Where(t => t.status== Status.New)
.OrderBy(t => t.StartTime)
.Take(maxAmount)
.ToListAsync();
tasks.ForEach((t) => t.status= Status.Launched);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return tasks;
}
catch (Exception e)
{
await transaction.RollbackAsync();
throw e;
}
});
但它似乎不起作用,因为在稍后尝试写回结果时,有时会出现重复条目的错误,因此看起来有两个线程正在处理同一任务。有没有更优雅的方式来做这样的事情?
比如更新状态并以原子方式返回?
或者一些完全不同的方法,实际上是解决此类问题的最新技术?可能会导致比赛状态。更新前锁定一行。此功能特定于DB引擎。您可以考虑将行分发到线程(服务器),而无需复制。如果您的数据是唯一登录的最终用户,则不必查询线程(服务器)中的所有行。相反,由当前登录的服务器(线程)处理。可能会导致竞争条件。更新前锁定一行。此功能特定于DB引擎。您可以考虑将行分发到线程(服务器),而无需复制。如果您的数据是唯一登录的最终用户,则不必查询线程(服务器)中的所有行。而是由当前登录服务器(线程)进行处理。