Предположим, у меня есть команда для редактирования одной записи статьи, называемой ArticleEditCommand
.CQRS, несколько узлов записи для одной записи агрегата, при сохранении параллелизма
- Пользователь 1 выдает
ArticleEditCommand
на основании V1 статьи. - Пользователь 2 выпускает
ArticleEditCommand
на основе V1 такой же
артикул.
Если я могу гарантировать, что мои узлы обрабатывать старые ArticleEditCommand
команд первыми, я могу быть уверен, что команда от пользователя 2 будет не потому, что команда пользователя 1 будет изменила версию статьи к V2.
Однако, если у меня есть два узла, обрабатывайте сообщения ArticleEditCommand
одновременно, даже если команды будут выполняться в очереди в правильном порядке, я не могу гарантировать, что узлы будут обрабатывать первую команду перед второй командой из-за всплеск в CPU или что-то подобное. Я мог бы использовать транзакцию sql для обновления статьи, где version = expectedVersion, и учитывать количество изменений записей, но мои правила более сложны и не могут жить исключительно в SQL. Я бы хотел, чтобы вся моя логика обработки команд была параллельной между ArticleEditCommand
сообщениями, которые изменяют эту же статью.
Я не хочу блокировать очередь во время обработки команды, потому что точка с несколькими обработчиками команд - это одновременное управление командами для масштабируемости. При этом я не против, чтобы эти команды обрабатывались последовательно, но только для одного экземпляра/идентификатора статьи. Я не ожидаю большого объема сообщений ArticleEditCommand
для отправки по одной статье.
С учетом сказанного, вот вопрос.
Есть ли способ обрабатывать команды последовательно по нескольким узлам для одного уникального объекта (запись базы данных), но одновременно обрабатывать все другие команды (отдельные записи базы данных)?
Или это проблема, которую я создал из-за недостаточного понимания CQRS и параллелизма?
Является ли это проблемой, которую обычно решали брокеры сообщений? Например, Windows Service Bus, MSMQ/NServiceBus и т. Д.?
EDIT: Я думаю, что я знаю, как справиться с этим сейчас. Когда пользователь 2 выдает ArticleEditCommand
, исключение должно быть выбрано для пользователя, позволяющего им знать, что текущая ожидающая операция над этой статьей должна быть завершена до этого момента, чтобы поставить в очередь ArticleEditCommand
. Таким образом, в очереди нет двух сообщений ArticleEditCommand
, которые влияют на одну и ту же статью.
Ваше право. Мне было любопытно больше всего. Я уверен, что кто-то наткнулся на него, и мне было интересно, как с ним справиться. –