知识卡片

事件实体的属性设计:全局唯一ID避免重复消费,业务属性不可变

普通读书笔记卡

内容

一个事件实体由基本属性和业务属性两部分组成。基本属性至少包含事件唯一标识、发生时间、事件类型、事件源,用来记录事件自身及其发生背景;其中事件唯一标识必须是全局唯一的,这样事件才能无歧义地在多个限界上下文之间传递,而且订阅方可以借助这个ID的主键约束特性,天然避免同一条事件消息被重复消费两次。业务属性则记录事件发生那一刻相关的业务数据,会随事件数据一起发布给订阅方,供订阅方开展下一步业务处理。这里有一条重要约束:事件实体的业务数据一旦写入就不可更改——如果业务数据后续发生了变化,不是去修改已有的事件实体,而是产生一个新的领域事件、把新数据写入一个新的事件实体。这个设计和值对象”不可变、用新对象整体替换旧对象”的思路是同源的:事件本身代表的是”过去某一时刻发生的事实”,事实本身不应该被事后篡改,任何变化都应该体现为一个新的事件,而不是对历史事件的编辑,这样才能保证事件流真实反映业务发生的时间顺序。

参考来源

- 位置:第9章《领域事件:解耦微服务的关键》"9.3 领域事件驱动实现机制","1. 事件构建和发布"(源文件:_epub-src/OEBPS/Text/chapter3-5-3.xhtml) - 结论依据:原文说明"事件实体的基本属性至少应该包含事件唯一标识、发生时间、事件类型和事件源,其中,事件唯一标识应该是全局唯一的……事件ID的唯一性和时序性的特点,通过主键约束可以避免事件消息的重复消费……领域事件发生后,领域事件的业务数据经过加工后被写入事件实体中,写入后的业务数据就不可以更改了",直接支撑本卡片结论。 - 原始内容:事件唯一标识应该是全局唯一的,以便事件通过ID能够无歧义地在多个限界上下文之间传递。事件ID的唯一性和时序性的特点,通过主键约束可以避免事件消息的重复消费……写入后的业务数据就不可以更改了。如果业务数据在业务逻辑处理时发生了变更,就会产生新的领域事件。