如何使用 DDD 在 CQRS 架构中使用 sagas?
How to use sagas in a CQRS architecture using DDD?
我正在使用 DDD 设计 CQRS 应用程序,想知道如何实现以下场景:
- 一个
Participant
聚合可以被多个ParticipantEntry
聚合引用
- 一个
AddParticipantInfoCommand
被下发给Command端,其中包含了Participant
和一个ParticipantEntry
的所有信息(类似于一个Order
和一个OrderLineItem
)
检查Participant是否已经存在,如果不存在则创建Participant的逻辑应该在哪里实现?
- 是否应该在 Saga 中完成,首先检查域模型是否存在
Participant
,如果没有找到,则发出 AddParticipantCommand
,然后发出 AddParticipantEntry
命令包含 Participant ID
?
- 这应该完全由领域模型本身的聚合根来完成吗?
Where should the logic be implemented that checks whether the Participant already exists and if it doesn't exist, creates the Participant?
在大多数情况下,这种行为应该在参与者集合本身的控制之下。
当您需要协调跨多个事务边界的更改时,流程很有用。但是,可以在同一事务中管理对同一聚合的两次更改。
您可以将此实现为在同一聚合上运行的两个不同事务,并进行协调;但是过程的额外复杂性并没有带来任何好处。将单个命令发送到聚合并允许它决定采取什么操作来保持正确的不变性要简单得多。
Sagas 尤其是一种用于恢复多个事务的模式。 Yan Cui 的 How the Saga Pattern manages failures with AWS Lambda and Step Functions 很好地说明了旅行预订的传奇故事。
(注意:"saga" 的定义存在相当大的混淆;NServiceBus 社区倾向于以与 Garia-Molina and Salem. kellabyte's Clarifying the Saga Pattern 调查混淆时最初描述的略有不同的方式来理解该术语。)
您不一定需要 sagas 来处理这种情况。看看我的博客 post 为什么 不 创建聚合根,以及应该怎么做:
我正在使用 DDD 设计 CQRS 应用程序,想知道如何实现以下场景:
- 一个
Participant
聚合可以被多个ParticipantEntry
聚合引用 - 一个
AddParticipantInfoCommand
被下发给Command端,其中包含了Participant
和一个ParticipantEntry
的所有信息(类似于一个Order
和一个OrderLineItem
)
检查Participant是否已经存在,如果不存在则创建Participant的逻辑应该在哪里实现?
- 是否应该在 Saga 中完成,首先检查域模型是否存在
Participant
,如果没有找到,则发出AddParticipantCommand
,然后发出AddParticipantEntry
命令包含Participant ID
? - 这应该完全由领域模型本身的聚合根来完成吗?
Where should the logic be implemented that checks whether the Participant already exists and if it doesn't exist, creates the Participant?
在大多数情况下,这种行为应该在参与者集合本身的控制之下。
当您需要协调跨多个事务边界的更改时,流程很有用。但是,可以在同一事务中管理对同一聚合的两次更改。
您可以将此实现为在同一聚合上运行的两个不同事务,并进行协调;但是过程的额外复杂性并没有带来任何好处。将单个命令发送到聚合并允许它决定采取什么操作来保持正确的不变性要简单得多。
Sagas 尤其是一种用于恢复多个事务的模式。 Yan Cui 的 How the Saga Pattern manages failures with AWS Lambda and Step Functions 很好地说明了旅行预订的传奇故事。
(注意:"saga" 的定义存在相当大的混淆;NServiceBus 社区倾向于以与 Garia-Molina and Salem. kellabyte's Clarifying the Saga Pattern 调查混淆时最初描述的略有不同的方式来理解该术语。)
您不一定需要 sagas 来处理这种情况。看看我的博客 post 为什么 不 创建聚合根,以及应该怎么做: