我需要实现悲观的并发控制。
基本上,我想等待动作完成后再允许第二次执行,因为我希望一次只存在一个具有特定值的行。
示例:
// 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,但它仅描述了如何处理更新和删除而不是插入的冲突。