首页 > 解决方案 > 在 EF Core 中实现悲观并发控制

问题描述

我需要实现悲观并发控制。

基本上,我想等待一个动作完成,然后再允许它第二次执行,因为我希望一次只存在具有特定值的 1 行。

例子:

// I would like to block concurrent execution of this method (lock it until it's finished)
[HttpPost("open")]
public async Task<IActionResult> Open(ReportCashDrawerStateRequest request)
{
    ...

    // CONCURRENCY PROBLEM HERE: 
    // This check for uniqueness will pass if Open will be executed concurrently 
    // before SaveChangesAsync is called which will result in duplicate rows
    if (await _db.CashDrawerStates.AnyAsync(s => s.CashDrawerId == request.CashDrawerId && s.EndTime == null)) 
        return UnprocessableEntity("Already open");

    var cashDrawerState = new CashDrawerState
    {
        CashDrawerId = request.CashDrawerId,
        StartTime = DateTime.UtcNow,
        StartedById = User.GetUserId(),
        StartingCashAmount = request.CashAmount
    };

    // because check above will pass this will result in having 2 rows with EndTime==null 
    // which is unwanted.
    _db.CashDrawerStates.Add(cashDrawerState);
    await _db.SaveChangesAsync();

    ...
}

这是一个业务逻辑要求,我认为添加唯一约束(索引)可以解决这个问题。

但是有没有办法通过在 Open 方法中实现某种锁定而不在数据库列上添加唯一约束来解决这个问题?

我阅读了https://docs.microsoft.com/en-us/ef/core/saving/concurrency但它只描述了处理更新和删除的冲突,而不是插入。

标签: c#asp.net-coreasp.net-core-mvcentity-framework-core

解决方案


推荐阅读