Architecture 在长时间运行的事务中使用最小聚合的体系结构问题

Architecture 在长时间运行的事务中使用最小聚合的体系结构问题,architecture,domain-driven-design,event-sourcing,aggregateroot,saga,Architecture,Domain Driven Design,Event Sourcing,Aggregateroot,Saga,我正试图遵循总体设计 我理解,由于他的系列文章中提到的许多原因,以及许多DDD从业者都建议将总量保持在尽可能小的水平 但这会在聚合主机内创建一个处理无关命令属性的问题 我有一个传入命令,其中包含系统完整执行事务所需的信息。命令中包含的信息不适合单个聚合,因为它们是最小的 因此,我认为这是一个长期运行的交易。我使用saga模式控制整个事务流 包装此长时间运行事务中涉及的聚合的每个主机都会引发一个域事件。该域事件随后被saga截获,saga随后发出后续命令,依此类推,直到业务事务成功进行或完全失败

我正试图遵循总体设计

我理解,由于他的系列文章中提到的许多原因,以及许多DDD从业者都建议将总量保持在尽可能小的水平

但这会在聚合主机内创建一个处理无关命令属性的问题

我有一个传入命令,其中包含系统完整执行事务所需的信息。命令中包含的信息不适合单个聚合,因为它们是最小的

因此,我认为这是一个长期运行的交易。我使用saga模式控制整个事务流

包装此长时间运行事务中涉及的聚合的每个主机都会引发一个域事件。该域事件随后被saga截获,saga随后发出后续命令,依此类推,直到业务事务成功进行或完全失败

如果我们想象一个场景,我们有这样一个命令:

从对话Z中的参与者Y发送消息X

例如,此命令将被消息的主机拦截

此主机将对消息聚合进行重新水化,告诉它验证事务的第一部分:

从参与者Y发送消息X

拦截该命令的同一主机随后必须引发一个域事件,例如

MessageCreated,这里的问题是MessageCreated事件需要携带其余的业务事务细节

在对话Z中

以便后续聚合执行事务的其余部分

由于消息聚合不关心会话ID,因此它的宿主需要保留该信息(从聚合的角度来看是不必要的)

当聚合批准事务时,主机必须创建一个域事件,比如MessageCreated*并将ConversationId附加到它

我在这里担心的是,通过将业务事务执行不需要的信息保留在主机内,随着时间的推移,最多会出现更多的业务需求,最坏的情况下可能会在主机之间产生逻辑耦合

就我的问题:


这被认为是处理长时间运行事务的安全方法吗?如果不是,那么什么是更好的选择?

为了将来的操作,需要在操作之间传播不相关的数据,这表明重新设计可能是有益的。这是我第一次听说聚合设计,但总体思路似乎是,在聚合上下文中,对聚合的操作不应使其任何部分处于无效状态。这部传奇背后的总体思想是,状态的变化是一个事件,事件发生时应该进行广播,操作应该由某些事件触发

实现这一点的一种方法是重新考虑消息不依赖于对话的决定。例:

消息(uuid、内容、时间戳、参与者id、会话id)

  • 规则:
  • 创建事件:消息\u已创建
  • 收听活动:
  • 参与者(uuid、名字、姓氏、电子邮件)

  • 规则:
  • 创建活动:创建参与者,更改电子邮件
  • 收听活动:
  • 对话(uuid、消息ID列表、参与者ID列表)

  • 规则:所有消息必须属于对话中的参与者
  • 创建事件:创建会议、添加人员、添加人员、添加消息
  • 侦听事件:消息\u已创建
  • 考虑到这些总量和事件,一种方法是:

  • 在对话Z中从参与者Y接收命令
    发送消息X
  • 创建消息(uuid,X,Y,Z)->消息\u已创建
  • 对话接收事件->添加的消息(如果参与对话)

  • 为了将来的操作,需要在操作之间传播不相关的数据,这表明一些重新设计可能是有益的。这是我第一次听说聚合设计,但总体思路似乎是,在聚合上下文中,对聚合的操作不应使其任何部分处于无效状态。这部传奇背后的总体思想是,状态的变化是一个事件,事件发生时应该进行广播,操作应该由某些事件触发

    实现这一点的一种方法是重新考虑消息不依赖于对话的决定。例:

    消息(uuid、内容、时间戳、参与者id、会话id)

  • 规则:
  • 创建事件:消息\u已创建
  • 收听活动:
  • 参与者(uuid、名字、姓氏、电子邮件)

  • 规则:
  • 创建活动:创建参与者,更改电子邮件
  • 收听活动:
  • 对话(uuid、消息ID列表、参与者ID列表)

  • 规则:所有消息必须属于对话中的参与者
  • 创建事件:创建会议、添加人员、添加人员、添加消息
  • 侦听事件:消息\u已创建
  • 考虑到这些总量和事件,一种方法是:

  • 在对话Z中从参与者Y接收命令
    发送消息X
  • 创建消息(uuid,X,Y,Z)->消息\u已创建
  • 对话接收事件->添加的消息(如果参与对话)

  • 您的问题不清楚您是如何以及为什么以这种方式设计聚合的。你提到它们必须是最小的,但我不认为这是最重要的方面。集合需要实现其目标。只有当它们太大而无法使用时,大小才起作用。例如,一次可能有几年价值的谈话