在EF Core中实现悲观并发控制

时间:2019-02-19 12:14:57

标签: c# asp.net-core asp.net-core-mvc entity-framework-core

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

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

示例:

// 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,但它仅描述了如何处理更新和删除而不是插入的冲突。

0 个答案:

没有答案