Поддерживать связь между агрегатами - PullRequest
3 голосов
/ 09 мая 2020

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

У меня есть два агрегата, один для «Команда» и один для «Событие», в контекст фестиваля со следующим кодом:

@Aggregate
public class Event {
    @AggregateIdentifier
    private EventId eventId;
    private Set<TeamId> teams; // List of associated teams

... protected constructor, getters/setters and command handlers ...
}
@Aggregate
public class Team {
    @AggregateIdentifier
    private TeamId teamId;
    private EventId eventId; // Owning event

... protected constructor, getters/setters and command handlers ...
}

Команда всегда должна быть связана с событием (через eventId). Событие содержит список связанных команд (через набор идентификаторов команды). Когда команда создается (CreateTeamCommand) на агрегате Team, я хотел бы, чтобы TeamId, установленный на агрегате Event, был обновлен идентификатором команды вновь созданной команды. Если выполняется команда «DeleteEventCommand» на агрегате событий, все команды, связанные с событием, также должны быть удалены. Если команда перемещается из одного события в другое событие (MoveTeamToEventCommand) в совокупности команд, идентификатор события в совокупности команд должен быть обновлен, но TeamId должен быть удален из старой совокупности событий и добавлен в новую совокупность событий.

Моя текущая идея заключалась в том, чтобы создать сагу, в которой я бы запускал SagaLifecycle.associateWith как для eventId в агрегате Event, так и для teamId в агрегате Team с @StartSaga в «CreateTeamCommand» (по сути, впервые связь начинается), а затем имеет обработчик событий для каждого события, которое влияет на отношения. Моя основная проблема с этим решением:

1: Это означало бы, что у меня была бы уникальная сага для каждой возможной комбинации команды и события. Это могло бы вызвать проблемы с производительностью, если бы оно было масштабировано, например. 1 миллион соревнований с участием 50 команд в каждом? (Это нереально c для этого сценария, но актуально для общего решения для поддержания отношений между агрегатами).

2: Это потребовало бы, чтобы у меня были специальные команды и обработчики событий, предназначенные для обработки обновления команд в команде список совокупности событий, поскольку результирующие события не должны обрабатываться в саге, чтобы избежать бесконечного l oop обновляемых ссылок.

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

1 Ответ

2 голосов
/ 10 мая 2020

Событие содержит список связанных команд (с помощью набора идентификаторов команд).

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

Я думаю, вам нужно, чтобы ваша читающая сторона знала об этом. Ваша модель чтения для одного «события» может прослушивать CreateTeamCommand и MoveTeamToEventCommand, а также все другие события, связанные с «событием», и соответственно строить проекцию. Помните, не создавайте свои агрегаты с учетом проблем, связанных с запросами .

Если выполняется команда «DeleteEventCommand» на агрегате событий, все команды, связанные с событием, также должны

Здесь несколько вещей:

  • Опять же, ваша сторона чтения может прослушивать это событие и соответственно обновлять прогнозы.
  • Вы также можете начать выполнение проверки соответствующих обработчиков команд для агрегата Team, чтобы проверить, существует ли Event перед выполнением операций. Это не будет иметь точной синхронизации c, но будет охватывать большинство случаев (см. «Как я могу проверить, что идентификатор клиента действительно существует, когда я размещаю заказ?» Раздел здесь ).
  • Если вы действительно хотите удалить связанные агрегаты Team с обратной стороны события DeleteEventCommand, вам необходимо обработать это внутри Saga , поскольку у вас нет возможности выполните это способом atomi c без утечки специфики системы хранения данных в вашу модель предметной области. Итак, вам нужны определенные повторы и идемпотентность, которые вам может дать сага. Это не совсем то, что вы предлагаете здесь, но связанный с этим факт состоит в том, что одна команда не может воздействовать на набор агрегатов, см. «Как я могу обновить набор агрегатов с помощью одной команды?» раздел здесь .
...