Domain driven design DDD:每个聚合一个事务

Domain driven design DDD:每个聚合一个事务,domain-driven-design,Domain Driven Design,下面有一个答案 在您的示例中,这非常简单:当客户放置 对于100个项目,将生成并发布一个域事件。然后 您有一个处理程序,它将检查订单是否符合 客户促销规则,如果有,则发出命令 将产生将客户端状态更改为VIP的结果 我认为很清楚客户是否存在,但如果客户将根据相同的操作(订单提交)创建,该怎么办?创建两个事件。一个用于正在创建的用户,一个用于订单本身。我猜在代码方面,您无论如何都会调用createUser例程,然后抛出第一个事件。在标题中,您颠倒了规则:“每个事务一个聚合”。也就是说,通过一次更新一

下面有一个答案

在您的示例中,这非常简单:当客户放置 对于100个项目,将生成并发布一个域事件。然后 您有一个处理程序,它将检查订单是否符合 客户促销规则,如果有,则发出命令 将产生将客户端状态更改为VIP的结果


我认为很清楚客户是否存在,但如果客户将根据相同的操作(订单提交)创建,该怎么办?

创建两个事件。一个用于正在创建的用户,一个用于订单本身。我猜在代码方面,您无论如何都会调用createUser例程,然后抛出第一个事件。

在标题中,您颠倒了规则:“每个事务一个聚合”。也就是说,通过一次更新一个聚合来更改域

您所做的更新可以是任意复杂的

我认为很清楚客户是否存在,但是如果客户将根据相同的操作(订单提交)创建呢

因此,您可以使用VIP属性集创建客户。它仍然是一个聚合(客户),因此允许在处理单个命令时进行多个更改

也就是说,一切都取决于如何正确地对聚合进行建模。在DDD中,状态(VIP标志)、依赖于该标志的规则以及允许您更改该标志的规则;所有这些都应该是同一个聚合的一部分。因此,请关注这一原则,与您的领域专家讨论需求,并探索正确的模式是否是在客户聚合上设置标志,而不是在忠诚程序聚合中向集合中添加CustomerId

真实案例:作为客人点菜。因此,我们应该下订单并向客户咨询。将涉及2个AR。这意味着创建一个客户,然后将customerId传递给订单创建,然后创建一个订单,然后需要更新客户标志

右-如果这个模型是正确的,那么需要运行三个命令。每个命令都写入单个聚合。您可以使用域事件来发布写入的结果,这些写入需要成为链中下一个命令的一部分


如果您想使该过程自动化,那么可以将发出命令的人工操作员替换为。基本上,流程管理器是一个状态机;域事件是触发器,异步命令是操作。

例如,真实案例:作为来宾订购。因此,我们应该下订单并向客户咨询。将涉及2个AR。这意味着创建一个客户,然后将customerId传递给订单创建,然后创建一个订单,然后需要更新客户标志…不要忘记,如果简化了设计而没有太多缺点,那么您可以在一个事务中创建任意多的AR,因为创建操作没有争用(创建不是更新)。好的,UserCreated事件,那么在这种情况下事件处理程序应该做什么?创建订单?然后对于OrderCreated事件,我们需要更新Customer,对吗?若用户将被创建,但按顺序创建的不变量之一将失败,该怎么办?如何回滚刚刚创建的用户?