#azure #nosql #azure-cosmosdb
Вопрос:
У меня есть небольшая коллекция документов в разделе. Я хотел бы отметить точно одну из этих сущностей как включенную в разделе. Быть включенным означает, что в документе установлен isEnabled
флаг true. Когда документ обновляется или вставляется со isEnabled
значением true, в этой транзакции должны быть все остальные документы isEnabled:false
. Если документ удаляется или изменяется с isEnabled
true на false, то последний измененный документ должен стать включенным, если осталась какая-либо запись. Раздел никогда не должен переходить в несогласованное состояние. Должно быть возможно иметь только один включенный документ, если только нет нулевых документов
Существует ли схема реализации такого рода государства? Я попробовал несколько подходов, но во всех них, похоже, есть какие-то дыры.
Комментарии:
1.
I've attempted a few approaches but they all seem to have some holes in them
— Пожалуйста, отредактируйте свой вопрос и укажите подходы, которые вы пытались использовать, и проблемы, с которыми вы столкнулись с ними.2. Помогли ли предоставленные ответы решить вашу проблему? Если да, пожалуйста, подумайте о принятии одного из них.
Ответ №1:
Используйте уникальные ключи. И назови это disabledAt
вместо isEnabled
этого .
Когда вам нужно переключить активный документ, вы можете открыть транзакцию.
- Начать транзакцию
- В старом документе установите
disabledAt
текущую дату и время UTC или галочки - В новом документе установите
disabledAt
значение null или удалите его - Зафиксировать транзакцию
Вы можете выполнять транзакции с помощью SDK или с помощью пользовательских функций. Вероятно, вы также можете использовать пост-триггеры, поскольку они выполняются в рамках одной транзакции.
Это гарантирует, что у вас есть только один документ без значения для disabledAt
. Это работает, потому что вы можете выполнять транзакции с гарантированной согласованностью, пока вы находитесь в пределах одного раздела.
Ответ №2:
Моя мысль состояла бы в том, чтобы переместить это состояние в выделенный элемент, а не распределять его между элементами. Этот отдельный элемент метаданных для каждого раздела будет иметь свойство типа activeItemId
и будет иметь значение либо id
активного документа, либо null, если он не активен.
Активный элемент будет подвержен семантике выигрышей при последней записи, и вы можете использовать канал изменений или задание обслуживания для проверки на отсутствие, если вы не можете применить его на уровне приложения. Даже если в activeItemId
конечном итоге будет указано на удаленный элемент, попытка чтения с 404 может быть использована в качестве двойной проверки во время чтения.