【问题标题】:Inter-aggregate communication聚合间通信
【发布时间】:2023-03-31 03:15:01
【问题描述】:

我目前每个聚合根和两个聚合根有一个事件流,RoomRoomType

Room 的行为取决于 RoomType 它是什么。为了分离两个聚合,RoomType 仅表示为 Room 聚合中的 roomTypeId。 RoomType 的更改由 RoomTypeChanged 事件表示。

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

现在考虑以下用例:

当用户使RoomType 无效时,所有具有RoomtypeRooms 都应切换到备用RoomType

我想过几种方法,但似乎都有问题:

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

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

你会怎么解决这个问题?

【问题讨论】:

    标签: event-sourcing eventstoredb


    【解决方案1】:

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

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

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

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

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 每个房间类型的流程管理器的问题是它的状态如何更新。如果您在创建房间的同一命令中更新它,您现在需要事务以确保数据库状态保持一致(您有 2 个写入操作:房间和管理器)。另一方面,如果您从事件处理程序更新流程管理器,那么您有提到的同一问题 OP 的不同版本
      【解决方案3】:

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

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

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

      【讨论】:

      • 最终的一致性很好,但不一致不是。你怎么知道要等多久? 1 秒、1 分钟还是一天?如果您等待的时间不够长,您的数据就会不一致(不仅仅是您的读取模型)。
      • 花了很长时间才回答这个问题,但这里是。根据定义,最终一致性意味着系统可以容忍不一致的状态。如果您需要完全 100% 的始终一致性,请使用 ACID。要解决“多长时间”问题,您需要多次执行检查,直到数据稳定。例如,每分钟运行一次,直到没有更多房间要更新。然后,您可以在一小时内重新运行它。此外,为避免污染,您可以在另一个命令中访问该属性时进行额外检查,以确保您没有使用过时的数据。
      • 问题是你不知道什么时候没有更多房间可以更新,所以你必须一直运行它。说的有点夸张了,不过重点还是有的,你还要重播多久?您正在尝试通过从最终一致的源中读取来解决一致性问题。
      • 我知道这听起来有点疯狂,但这就是最终一致系统的工作方式。如果您停止向系统添加数据并继续运行该任务,那么在某些时候,旧数据将不会保留,系统将变得一致。当然,如果你继续运行操作,系统永远不会完全稳定,因为旧的操作稳定了,新的操作仍然未知。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      相关资源
      最近更新 更多