Как предотвратить исключение DuplateKeyException при использовании обновления MongoDB с оптимистичным параллелизмом (упрC#

Место общения программистов C#
Anonymous
Как предотвратить исключение DuplateKeyException при использовании обновления MongoDB с оптимистичным параллелизмом (упр

Сообщение Anonymous »

Я использую MongoDB с драйвером .NET и пытаюсь реализовать шаблон оптимистичного параллелизма с управлением версиями с помощью UpdateOneAsync и IsUpsert = true.
Вот мой код:

Код: Выделить всё

public Task UpsertAsync(User user, CancellationToken cancellationToken) =>
context.Users.UpdateOneAsync(
Builders.Filter.Eq(u => u.Id, user.Id) &
Builders.Filter.Lt(u => u.Version, user.Version),
Builders.Update
.SetOnInsert(u => u.Id, user.Id)
.Set(u => u.IsDeleted, user.IsDeleted)
.Set(u => u.Version, user.Version)
.Set(u => u.Name, user.Name)
.Set(u => u.UserName, user.UserName)
.Set(u => u.Media, user.Media),
new UpdateOptions { IsUpsert = true },
cancellationToken
);
Цель
  • Вставить документ, если он не существует
  • Обновить его, только если входящая версия больше сохраненной
Проблема
Когда документ уже существует с более высокой версией версия, фильтр не соответствует:

Код: Выделить всё

Id == user.Id AND Version < user.Version → false
Из-за IsUpsert = true MongoDB пытается вставить новый документ, что приводит к:

Код: Выделить всё

DuplicateKeyException (same Id)
Вопрос
Каков рекомендуемый способ обработки этого сценария?
  • Является ли перехват и игнорирование DuulateKeyException правильным/ожидаемым подходом в этом шаблоне?
  • Или есть лучший способ реализовать «обновление только в том случае, если версия более новая, в противном случае ничего не делайте» без попытки вставки?
Я пытаюсь сохранить эту операцию атомарной и избежать состояний гонки, поэтому я бы предпочел решение с одним запросом, если это возможно.
Буду признателен за любые рекомендации или рекомендации.

Вернуться в «C#»