Мы используем драйвер Mon go C#. Локально мой бэкэнд - это настоящая MongoDB, и на производстве в Azure - MS CosmosDB с интерфейсом Mon go.
My Mon go документ имеет версию. Я читаю документ, изменяю его, увеличиваю версию, пишу - и хочу быть уверенным, что никто не изменил документ между чтением и записью. Поэтому я использую версию в фильтре обновлений:
Итак, я делаю это:
var builder = Builders<SettingsStorage>.Filter;
var filter = builder.Eq(c => c.Id, myId) & builder.Eq(c => c.Version, versionAsReadBeforeUpdate);
await this.configurations.FindOneAndUpdateAsync(filter, updateDef);
Или это, просто чтобы быть уверенным:
var filter1 = Builders<SettingsStorage>.Filter.Eq(c => c.Id, myId);
var filter2 = Builders<SettingsStorage>.Filter.Eq(c => c.Version, versionAsReadBeforeUpdate);
var filter = Builders<SettingsStorage>.Filter.And(filter1, filter2);
await this.configurations.FindOneAndUpdateAsync(filter, updateDef);
Так если кто-то изменил документ между ними, версия также изменится, и фильтр потерпит неудачу. Я получу исключение «Команда findAndModify завершилась ошибкой: сбор ошибок дублированного ключа E11000: конфигурации не удалось _id или ограничение уникального ключа» и сможет запускать политики повторных попыток и т. Д. c.
Теперь дело в том, что он работает отлично с бэкэндом Mon go, но почти всегда это исключение возникает при повторном запуске CosmosDB, как при развертывании, так и в одной локальной среде. Это тот же звонок, это точно только один одновременный абонент. Так как же? Драйвер c# работает по-другому для CosmosDB? Что я могу попробовать или как это можно объяснить?
Примечание: с обычным фильтром, т.е. просто builder.Eq(c => c.Id, myId)
, обе среды ведут себя одинаково и работают правильно.