Мне нужно реализовать пессимистическое управление параллелизмом.
По сути, я хочу дождаться окончания действия, прежде чем разрешить его выполнение во второй раз, потому что я хочу, чтобы существовала только 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, но он описывает только обработку конфликта для обновлений и удаленийа не для вставок.