领域事件永远不会失败,因为它是对发生的事情的通知(注意过去时)。但是将生成该事件的操作可能会失败并且不会生成该事件。
你告诉我们的场景表明你并不是真的在做 DDD,你是在使用 DDD 词做 CRUD。是的,我知道你是新手,别担心,每个人都误解了 DDD,直到他们得到它(但这可能需要一些时间和大量练习)。
DDD 是关于识别领域模型抽象,而不是代码。代码是您实现该抽象的时候。很明显你没有进行正确的建模,因为领域专家应该告诉你如果产品缺货会发生什么。
接下来,此级别没有 db/acid 事务。这些是实现细节。DDD 的工作方式是确定业务需要在哪里使事物保持一致,这称为聚合。
订单已提交,该用例在此停止。当您发布OrderWasMade
事件时,会触发另一个用例(扣除库存或其他)。这是一个不同的业务场景,但不是“提交订单”的一部分。如果库存不足,则会发布另一个事件NotEnoughInventory
并触发另一个用例。我们在这里跟踪业务,并确定业务为完成订单而执行的每个步骤。
DDD 的艺术在于理解和识别精细的业务功能、涉及的聚合、做出决策的业务行为等,这与数据库或事务无关。
在 DDD 中,聚合是唯一需要使用工作单元的地方。
要回答您的问题:
似乎每个事件都在自己的事务范围内,这意味着系统需要一次打开多个到数据库的连接。因此,如果我使用 IIS 服务器,我必须启用 DTC,对吗?
不,事务、事件和分布式事务是不同的东西。IIS是一个web服务器,我想你想说的是SqlServer。您总是在 Web 应用程序中打开到数据库的多个连接,DTC 与它无关。实际上,这个问题告诉我,您需要阅读更多有关 DDD 的内容,而不仅仅是 Evans 的书。老实说,从 DDD pov 来看,您的要求没有多大意义。您知道 DD 的原则之一:数据库(如持久性细节)不存在。
域事件和域服务之间是否有任何关系
它们都是域的一部分,但它们具有不同的角色:
- 领域事件告诉世界领域发生了变化
- 域服务封装了没有自己持久状态的域行为(如计算税)
通常,应用程序服务(充当业务用例的主机)将使用域服务来验证约束或收集更改聚合所需的数据,从而生成一个或多个事件。聚合是持久化的,并且始终以原子方式持久化聚合,即数据库事务/工作单元。