将聚合和Domain事件与nosql存储一起使用

时间:2013-04-02 07:42:09

标签: nosql domain-driven-design aggregateroot aggregates domain-events

我实际上在DDD和NoSql字段上游荡。我现在有一个疑问:我需要从聚合中生成事件,我想使用NoSql存储。但是,如何确保事件保存在存储上以及聚合根上没有事务的更改? 这有道理吗?有没有办法在不被迫使用事件源或事务数据库的情况下执行此操作? 实际上我正在考虑实现一个2阶段提交算法,但从性能的角度看它似乎相当沉重...... 我是以错误的方式解决问题的吗? 塞满问题...... 谢谢你的每一个建议 恩里科

PS 我是stackoverflow的新手,所以任何建议/评论/ ...都非常受欢迎 恩里科

修改1

我需要事件通知聚合发生了什么事情,我应该对变化作出反应。当此类事件对业务逻辑很重要时,就会出现问题。据我所知,经过一夜的思考,我无法使用nosql存储来做这些事情。让我解释一下(大声思考:P):

  • 使用ES(第一个场景):我保存数据的“差异”。然后我产生一个与之相关的事件。 2次操作。
  • 使用ES(第2场景):我保存数据的“差异”。一个过程,观看ES并制作活动。但我只想拥有一个观察程序来确保事件的正确排序。
  • 使用ES(3d场景):幂等事件。事件可以由状态推断,并且事件的每次重新应用可以仅导致消费者的一次改变,可以具有多个“出列”过程,不可能发生重复。 1操作,但它给消费者带来了很大的限制。
  • 一般情况下:我保存聚合数据。然后我产生一个与之相关的事件。 2次操作。

现在问题变得更加广泛,当域事件是业务流程的基本组成部分时,是否可以使用域事件和nosql? 我认为这可能是一个更好的选择去关系...即使我需要添加相当多的机器来获得相同的表现。

编辑2 为了完整性,在google上搜索“domain events nosql idempotent”:http://svendvanderveken.wordpress.com/2011/08/26/transactional-event-based-nosql-storage/

1 个答案:

答案 0 :(得分:0)

如果您需要Event Sourcing,则应仅存储事件

这应该是序列:

  1. 聚合根收到command
  2. 它发起了适当的事件
  3. 存储事件
  4. 每个聚合的重新水化只能通过对它们执行事件来完成。如果您在初始化时测量性能问题,则可以创建聚合的快照,但这不需要两阶段提交,因为您可以通过批处理异步构建快照。

    但请注意,只有当您的申请为heavily concurrent并且您需要应对partition tolerance并采取补偿措施时,您才需要CQRS和/或事件采购。

    修改
    事件采购可替代对象状态的持久性。您要么存储事件,要么存储对象模型的状态。您可以保存快照,但它们只是性能工具:您的应用程序必须能够在没有它们的情况下工作。您可以将此类快照视为缓存技术。作为替代方案,您可以持久化对象状态(经典模型),但在这种情况下,您不需要存储事件。

    在我自己的DDD应用程序中,我使用observable entities来解耦(通过直接事件从存储库订阅)聚合及其持久性。例如,您的存储库可以订阅每个域事件,并执行应用程序所需的操作(持久存储到存储,调度到队列等等)。但作为一种持久性技术,Event Sourcing对于可观察对象状态的经典持久性来说是替代。在大多数情况下,您不需要两者。

    编辑2 最后一点:如果您选择ES,其中一个事件订阅者也可以构建关系read-model