2015-02-13 4 views
5

В настоящее время у меня есть один поток событий на каждый корень корня и два элемента счисления, Room и RoomType.Комбинированная связь

Поведение Room зависит от того, что такое RoomType. Чтобы разделить оба агрегата, RoomType представлен только как roomTypeId в совокупности Room. Изменение RoomType представлено мероприятием RoomTypeChanged.

RoomTypes может управляться отдельно и нуждается в другом агрегате.

Теперь рассмотрим следующий случай использования:

Когда пользователь аннулирует в RoomType, все Rooms, что есть, что Roomtype должен переключиться на запасной вариант RoomType.

Я думал несколько подходов, но все они кажутся проблематичными:

  1. Есть ли прослушиватель события прослушайте RoomTypeInvalidated -Event, и отправить SwitchToFallbackRoomType на всех Room -aggregates, которые имеют что Roomtype. Как бы это сделать? Невозможно узнать, у каких агрегатов есть Roomtype, если я не получу доступ к моей readmodel, которая кажется неправильной. Даже если бы я загружал все агрегаты, невозможно загрузить только агрегаты этого типа, так как я не могу загрузить подмножество всех потоков (используя geteventstore).

  2. Когда на RoomTypeChanged повторное -СОБЫТИИ к Room агрегату, вместо того, чтобы просто применить его, сделать проверку, чтобы убедиться в том, что до сих пор существует RoomType, но опять-таки, как бы я знать, какие RoomTypes существуют (я бы в такая же ситуация, как 1, но инвертированная)? Кроме того, кажется неправильным вводить логику в повторное использование событий, они должны просто представлять изменения состояния, я думаю.

Как вы решите это?

ответ

0

Почему бы не использовать диспетчера процессов для каждого номера и не иметь список комнат как свойство диспетчера процессов?
Запрос модели чтения из службы или из обработчика команд не гарантирует согласованную структуру. Что делать, если помещение было присвоено типу недействительной комнаты, но модель чтения еще не была обновлена? (это своего рода сценарий, с которым я сталкиваюсь)

+0

Проблема с диспетчером процесса в каждом номере - как это состояние обновляется. Если вы обновите его в той же команде, которая создает комнату, теперь вам нужны транзакции, чтобы гарантировать, что состояние БД остается согласованным (у вас есть 2 операции записи: комната и менеджер). Если, с другой стороны, вы обновляете диспетчер процессов из обработчика событий, то у вас есть другая версия той же проблемы, о которой упоминалось OP –

0

Решение этой проблемы, убедившись, что данные полностью согласованы каждый раз при работе с дизайном. Событие Sourcing предполагает, что система в конечном итоге соответствует, поэтому наличие несоответствий в считываемой модели является нормальным и ожидаемым.

Лучший способ решить эту проблему - запросить свою модель для всех комнат с новым недействительным TypeId (ваше решение 1). После обновления всех этих комнат есть вероятность, что есть несколько отставших, которые не были обновлены, поэтому вы повторно запускаете обработчик событий через несколько минут (скажем, минуту).

В этот момент (при условии, что ваши Команды проверяют правильность типа комнаты при создании Комнаты), невозможно создать новые комнаты со старым типом комнаты, а модель чтения для отставших должна быть уже стабилизирована. Таким образом, повторный запуск кода обновит все оставшееся.

+0

В конечном итоге согласованность в порядке, но несогласованности нет. Откуда вы знаете, как долго ждать? 1 секунда, 1 минута или день? Если вы не подождете достаточно долго, ваши данные несовместимы (а не только ваша модель чтения). – Kenneth

+0

Долго ждал ответа, но здесь идет. Конечная согласованность по определению подразумевает систему, которая допускает несогласованное состояние. Если вам нужна полная 100% -ная постоянная времени, перейдите к ACID. Чтобы решить проблему «сколько времени», вы выполняете проверку несколько раз, пока данные не стабилизируются. Например, запустите его каждую минуту, пока не будет больше номеров для обновления. И затем, вы можете снова запустить его через час. Кроме того, чтобы избежать заражения, вы можете выполнить дополнительную проверку при подключении этого свойства в другой команде, чтобы убедиться, что вы не используете устаревшие данные. –

+0

Проблема в том, что вы не знаете, когда больше нет комнат для обновления, поэтому вам придется продолжать работать навсегда. Это преувеличено, но точка все еще стоит, как долго вы продолжаете ее переигрывать? Вы пытаетесь решить проблему согласованности, читая из последовательного источника. – Kenneth

0

Мы работаем с той же проблемой, также комнатами и комнатами. Решение, с которым вы сталкиваетесь, вероятно, связано с реляционным, если это не проблема. Трудно и сбивать с толку думать о том, чтобы начать думать о поведении в другом направлении, основанном на данных. Я думаю, что для решения проблемы вам придется бросить вызов предлагаемому решению.

Когда мы передумали, мы закончили с агрегатами, такими как RoomAssignment и RoomAllocationSchedule, и обнаружили, что RoomType в основном используется для связи функций комнаты с внешними каналами/OTA.

Моделирование поведения мы должны действительно помогает (так как консистенция bounderies начинает иметь смысл), вместо данных моделирования и пытаются применять реляционную согласованное поведение на нем ...

Когда нам действительно нужно согласованность агрегатов, мы моделируем диспетчер процессов/сагу, который сам по себе является последовательным с транзакцией, и сообщаем об агрегатах. Таким образом, у нас есть агрегат «RoomAssignmentDirector», который гарантирует, что помещение будет выделено для проживания в комнате до того, как оно будет присвоено номеру комнаты и т. Д.

Надеюсь, что это поможет.