Репост из: .NET Разработчик
День 1686. #ЗаметкиНаПолях
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Окончание
Начало
Обработка исключений параллелизма
Теперь мы можем исправить предыдущий фрагмент кода.
Если два одновременных запроса проходят проверку IsOverlapping, только один может завершить вызов SaveChanges. Другой конкурентный запрос приведёт к несоответствию версии в базе данных и выдаст исключение DbUpdateConcurrencyException.
На случай конфликта параллелизма нам нужно добавить оператор try-catch, чтобы перехватить исключение DbUpdateConcurrencyException. То, как вы будете обрабатывать фактическое исключение, зависит от ваших бизнес-требований.
public Result Handle(
ReserveBooking command,
AppDbContext ctx)
{
var user = ctx.Users.GetById(command.UserId);
var apart = ctx.Aparts.GetById(command.ApartId);
var (start, end) = command;
if (ctx.Bookings.IsOverlapping(apart, start, end))
return Result.Failure(Errors.Overlap);
try
{
var booking = Booking
.Reserve(apart, user, start, end);
ctx.Add(booking);
ctx.SaveChanges();
return booking.Id;
}
catch (DbUpdateConcurrencyException)
{
return Result.Failure(Errors.Overlap);
}
}
Когда следует использовать оптимистический параллелизм?
Оптимистический параллелизм предполагает, что успешный сценарий также является наиболее вероятным. Он предполагает, что конфликты между транзакциями будут нечастыми и не блокирует данные. Это означает, что ваша система может лучше масштабироваться, поскольку нет блокировок, снижающих производительность.
Однако вам всё равно придётся ожидать конфликтов параллелизма и реализовать специальную логику для их обработки.
Оптимистический параллелизм — хороший выбор, если ваше приложение не ожидает большого количества конфликтов.
Другая причина использовать оптимистический параллелизм — когда вы не можете поддерживать открытое соединение с базой данных на протяжении всей транзакции. Это необходимо для пессимистической блокировки.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Окончание
Начало
Обработка исключений параллелизма
Теперь мы можем исправить предыдущий фрагмент кода.
Если два одновременных запроса проходят проверку IsOverlapping, только один может завершить вызов SaveChanges. Другой конкурентный запрос приведёт к несоответствию версии в базе данных и выдаст исключение DbUpdateConcurrencyException.
На случай конфликта параллелизма нам нужно добавить оператор try-catch, чтобы перехватить исключение DbUpdateConcurrencyException. То, как вы будете обрабатывать фактическое исключение, зависит от ваших бизнес-требований.
public Result Handle(
ReserveBooking command,
AppDbContext ctx)
{
var user = ctx.Users.GetById(command.UserId);
var apart = ctx.Aparts.GetById(command.ApartId);
var (start, end) = command;
if (ctx.Bookings.IsOverlapping(apart, start, end))
return Result.Failure(Errors.Overlap);
try
{
var booking = Booking
.Reserve(apart, user, start, end);
ctx.Add(booking);
ctx.SaveChanges();
return booking.Id;
}
catch (DbUpdateConcurrencyException)
{
return Result.Failure(Errors.Overlap);
}
}
Когда следует использовать оптимистический параллелизм?
Оптимистический параллелизм предполагает, что успешный сценарий также является наиболее вероятным. Он предполагает, что конфликты между транзакциями будут нечастыми и не блокирует данные. Это означает, что ваша система может лучше масштабироваться, поскольку нет блокировок, снижающих производительность.
Однако вам всё равно придётся ожидать конфликтов параллелизма и реализовать специальную логику для их обработки.
Оптимистический параллелизм — хороший выбор, если ваше приложение не ожидает большого количества конфликтов.
Другая причина использовать оптимистический параллелизм — когда вы не можете поддерживать открытое соединение с базой данных на протяжении всей транзакции. Это необходимо для пессимистической блокировки.
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking