如何存储变异状态,事件驱动的编程?

时间:2018-12-08 09:50:04

标签: events event-handling domain-driven-design data-modeling cqrs

我有以下情况,我挠头。我有一个汇总,可以称之为保留,我有一个事件。一些事件将导致聚合的状态发生突变。此状态中的某些功能正常,它自然地属于总计-例如“计算税”。我要说的某些状态比技术更重要,例如,如果消息发送到第三方系统,则称其为“ isMessageSentToASystem”。在数据库中,我有两个表,一个表用于汇总事件。我看到两个保持状态的state虫:

1)我只能将更改的内容保留在绑定到该事件的第三个表中。这样,我将有效地收到修订日志。我认为这不太适合我的应用程序。它将使我的聚合保持不变

2)我将接受我的聚合是可变的,并且将所有功能上的重要状态写入其中,就像“ calculatedTax”一样。但是这里有一个问题,我应该如何处理像“ isMessageSenttoSystemA”这样的技术状态,我感觉该状态不属于聚合本身,而是事件的副作用。

我可以创建第三个表并将其绑定到可以编写技术状态的事件吗?我应该如何命名这样的表?我真的很难找到正确的名字吗?

更新:我不确定问题是否清楚,但是我最感兴趣的是如何对数据库中的数据建模。我使用RDBMS。

UPDATE2:我不想实现事件源,我认为这不是拥有事件驱动架构的先决条件。

2 个答案:

答案 0 :(得分:1)

未变异的状态和变异事件属于集合。

我强烈建议您下载Vaughn Vernon的代码,他是《实现域驱动设计(IDDD)》一书的作者。

以下是包含您问题答案的课程:

https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_common/src/main/java/com/saasovation/common/domain/model/EventSourcedRootEntity.java

请注意此处的逻辑以及与EventStore的关系,这里有一个突变事件列表,有效改变您的实体的事件以及指向未突变版本的指针。那些用于事件存储的实现,请查看MySQL实现以了解。

https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_common/src/main/java/com/saasovation/common/port/adapter/persistence/eventsourcing/mysql/MySQLJDBCEventStore.java

在加载方面,事件存储中的所有事件均被加载并应用于源自事件的根实体,但未存储在变异事件列表中。因此,您的实体状态将还原到审核日志的最新版本,并且此列表中的内存中会跟踪所有修改,保存后会将其刷新到数据库中。

关于事件存储本身的结构,这非常简单:

CREATE TABLE `tbl_es_event_store` (
    `event_id` bigint(20) NOT NULL auto_increment,
    `event_body` varchar(65000) NOT NULL,
    `event_type` varchar(250) NOT NULL,
    `stream_name` varchar(250) NOT NULL,
    `stream_version` int(11) NOT NULL,
    KEY (`stream_name`),
    UNIQUE KEY (`stream_name`, `stream_version`),
    PRIMARY KEY (`event_id`)
) ENGINE=InnoDB;

答案 1 :(得分:0)

isMessageSentToSystemA是一个查询端服务,您可以在分派命令和更改聚合之前检查该约束。 您还可以使用SAGA执行分布式事务并管理用例的工作流程