维护聚合之间的引用

Maintain reference between aggregates

我正在努力思考如何维护两个聚合之间的 id 引用,例如。当任何一方发生影响关系的事件时,另一方也会以最终一致的方式更新。

我有两个聚合,一个用于 "Team",一个用于 "Event",在节日的上下文中,代码如下:

@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)。事件包含关联团队的列表(通过团队 ID 集)。 在 Team 聚合上创建团队 (CreateTeamCommand) 时,我希望 Event 聚合上设置的 TeamId 更新为新创建团队的团队 ID。 如果在事件聚合上执行命令 "DeleteEventCommand",则还应删除与事件关联的所有团队。 如果团队从一个事件移动到团队聚合上的另一个事件 (MoveTeamToEventCommand),则应更新团队聚合上的 eventId,但应将 TeamId 从旧事件聚合中删除并添加到新事件聚合中。

我目前的想法是创建一个传奇,我将 运行 SagaLifecycle.associateWith 用于事件聚合上的 eventId 和团队聚合上的 teamId,并在 [=30 上使用 @StartSaga =](基本上是关系第一次开始),然后为影响关系的每个事件都有一个事件处理程序。我对这个解决方案的主要问题是:

1:这意味着我会为团队和事件的每种可能组合创建一个独特的传奇。如果将其缩放为例如,这会在性能方面造成麻烦吗? 100 万场比赛,每场比赛有 50 支球队? (这对于这种情况是不现实的,但与维护聚合之间关系的通用解决方案相关)。

2:这需要我有自定义命令和事件处理程序,专门用于处理事件聚合团队列表中团队的更新,因为不应在传奇中处理生成的事件,以避免更新引用的无限循环.

感谢您阅读这个小故事,我希望有人可以确认我在正确的轨道上,或者为我指明正确解决方案的方向。

An event contains a list of associated teams (through the team id set).

如果您在这里的 "An event aggregate" 是指 "An event",我认为您的活动汇总不需要团队 ID。如果您认为确实如此,那么理解您对此的推理会很棒。

我认为您需要的是通过阅读了解这一点。单个 "Event" 的读取模型可以监听 CreateTeamCommandMoveTeamToEventCommand 以及所有其他 "Event" 相关事件,并相应地建立投影。记住,don't design your aggregates with querying concerns in mind.

If the command "DeleteEventCommand" on the Event aggregate is executed, all teams associated to the event should also be deleted.

这里有几件事:

  • 同样,您的阅读方可以侦听此事件,并相应地更新预测。
  • 您还可以开始对 Team 聚合的相关命令处理程序执行验证,以在执行操作之前检查 Event 是否存在。这不会有完全同步,但会涵盖大多数情况(请参阅 "How can I verify that a customer ID really exists when I place an order?" 部分 here)。
  • 如果你真的想删除 DeleteEventCommand 事件后面的关联 Team 聚合,你需要在 Saga 中处理它作为您无法以原子方式执行此操作 w/o 将数据存储系统细节泄漏到您的域模型中。因此,您需要一定的重试和幂等性需求,而传奇可以为您提供。这不完全是你在这里的建议,但相关的事实是单个命令不能作用于一组聚合,参见 "How can I update a set of aggregates with a single command?" 部分 here