使用 DDD/Repo/UoW/Serv 的领域事件

Domain Events Using DDD/Repo/UoW/Serv

我正在为工作制作休息服务,使用:

项目简介:

问题来了,我应该在哪里以及如何实施这些事件?

假设我有一个 "User" 实体,它需要一百个字段,我在实体内部有一个工厂方法,它需要一百个参数长度,这根本不是最优的,然后事件会在知道它被添加到数据库之前就被触发了吗?所以我最终向用户发送了一封电子邮件,但是数据库不可用,所以根本没有创建用户。

我知道在 DDD 中你应该设置和聚合并在实体等中包含事件,但是即使写入数据库不成功,事件也会被触发......假设我有一个需要一百个的模型字段,在 Dao/Entity class 中有一个工厂方法是不合适的,它需要一百个参数?

提前致谢。 - 真诚沮丧的人

沮丧的人,

通常,您会希望将更改和事件保存在同一个数据库事务中。通过这种方式,您可以保证您的事件仅在写入您的更改时写入。

接下来,您应该考虑仅在写入数据库后才触发电子邮件警报。考虑一个分布式过程,您可以在其中从数据库中获取新事件并将它们发布到队列中。然后,您可以使用不同的流程来提取和处理它们(例如,向用户发送电子邮件)。

一般来说,尝试在没有事务保证的情况下在一个进程中完成所有工作会导致状态不一致。将您的工作分解成您可以保证的小工作单元,并且不要害怕将工作卸载到队列中,您可以在队列中同样保证工作是否会完成。

关于您的其他问题,

  • 理想情况下,您应该将根实体包装在聚合中并在那里维护您的逻辑
  • 您应该只有根实体的存储库。他们应该加载任何依赖的子实体。子实体不需要独立加载,因此不需要存储库
  • 如果你处理的是上百列,你能不能把这些表和实体垂直分区,变成很多Roots?也就是说,是否所有列都在相同的 time/use 情况下得到更新?从读取的角度来看,拥有这样大小的实体是低效的,但如果字段是从不同的用例写入的,那么在写入时也是如此,并且在大量写入场景下将成为瓶颈。

希望对您有所帮助。

对域模型的大多数更改都应遵循此顺序

  1. 决定写下什么
  2. 写下来
  3. 向全世界讲述您写下的内容

1 happens-before 2.

2 happens-before 3.

尝试让 2 和 3 并发打开了一个需要解决昂贵问题的世界。所以不要那样做?

一种适合某些情况的替代方法是在将更改写入模型时记下事件(在步骤 2 中),然后使用存储的事件列表来决定广播什么(在步骤 3 中) .

见乌迪大汉:Reliable Messaging without Distributed Transactions