5

我目前每个聚合根和两个聚合根有一个事件流,Room并且RoomType.

a 的行为Room取决于RoomType它是什么。为了分离两个聚合, TheRoomType仅表示为聚合中的 roomTypeId Room。变化RoomTypeRoomTypeChanged事件表示。

可以单独管理,RoomTypes并且需要在不同的聚合中。

现在考虑以下用例:

当用户使 a 无效时RoomType,所有Rooms拥有它的人都Roomtype应该切换到 fallback RoomType

我已经想到了几种方法,但它们似乎都有问题:

  1. 让事件侦听器侦听-event,并在所有具有该事件的 -aggregates 上RoomTypeInvalidated发送一个。我该怎么做呢?除非我访问我的 readmodel,否则无法知道哪些聚合具有它,这似乎不正确。即使我要加载所有聚合,也无法仅加载该类型的聚合,因为我无法加载所有流的子集(使用 geteventstore)。SwitchToFallbackRoomTypeRoomRoomtypeRoomtype

  2. 当将RoomTypeChanged-events 重新应用到Room聚合时,而不是仅仅应用它,检查它是否RoomType仍然存在,但话又说回来,我怎么知道哪个RoomTypes存在(我会和 1 处于相同的情况,但倒置) ? 此外,在重新应用事件时加入逻辑似乎是错误的,我认为它们应该只代表状态变化。

你会如何解决这个问题?

4

3 回答 3

1

我们正在处理同样的问题,房间和房间类型也是如此。您遇到问题的解决方案可能是从不存在问题的关系映射的。在一个非常受数据驱动的领域中开始思考行为是很难和令人困惑的。我认为要解决问题,您必须挑战提出的解决方案。

重新思考时,我们最终得到了 RoomAssignment 和 RoomAllocationSchedule 之类的聚合,并发现 RoomType 主要用于将房间功能传达给外部通道/OTA。

对我们需要的行为进行建模确实很有帮助(因为一致性边界开始变得有意义),而不是对数据进行建模并尝试对其强制执行关系一致的行为......

当我们真的需要跨聚合的一致性时,我们会建模一个流程管理器/saga,它本身在事务上是一致的,并向聚合发送消息。因此,我们有一个“RoomAssignmentDirector”聚合,可确保在将房间分配给客房住宿之前将其分配给客房住宿等。

希望能帮助到你。

于 2015-10-07T12:40:06.390 回答
0

为什么不使用每个房间类型的流程管理器并将房间列表作为流程管理器的属性?
从服务或命令处理程序查询读取模型并不能保证一致的框架。如果房间被分配到无效房间类型但读取模型尚未更新怎么办?(这就是我面临的情况)

于 2015-06-18T20:11:16.793 回答
0

通过确保数据每次都完全一致来解决这个问题不符合设计。事件溯源假定系统最终是一致的,因此在读取模型处出现不一致是正常的和预期的。

解决此问题的最佳方法是使用新的无效 TypeId 查询所有房间的读取模型(您的解决方案 1)。更新所有这些房间后,可能会有一些未更新的落后者,因此您稍后(假设一分钟)重新运行事件处理程序。

那时(假设您的命令在创建房间时检查房间类型的有效性)不可能使用旧房间类型创建新房间,并且落后者的读取模型应该已经稳定。因此,重新运行代码将更新剩余的所有内容。

于 2015-09-24T19:29:36.120 回答