首页/开发/系统分析与架构设计速查/领域事件(Domain Event)
需求分析与建模61 条

领域事件(Domain Event)

领域事件表示领域中已经发生的事实,命名用过去时(订单已提交);它用于解耦聚合间协作,与对外发布的集成事件在用途与结构上有所区别。

领域事件是什么

领域事件表示业务领域中已经发生的事实,命名用过去时并带业务语义,例如“订单已提交”“支付已完成”。它用于解耦聚合之间的协作:本聚合完成状态变更后发布事件,其他聚合或上下文订阅处理,从而在无法使用单一事务的场景下达成最终一致。领域事件面向本上下文内部;对外发布时需要转换为更稳定的集成事件,并带上版本号。

基本信息

命名过去时加业务语义,如 OrderSubmitted、PaymentCompleted
内容事件 ID、发生时间、聚合标识与关键业务数据
与集成事件领域事件面向本上下文;集成事件面向外部,更稳定且需版本化
发布时机与状态变更在同一事务内写入,事务提交后再对外发送
消费要求消费端幂等,事件可重投递且顺序只在同一聚合键内保证

命名对照

表达示例说明
命令(祈使句)SubmitOrder表达意图,可能被拒绝
领域事件(过去时)OrderSubmitted描述事实,已发生不可撤回
集成事件(过去时加版本)sales.order.submitted.v1对外契约,需要兼容演进
查询(问句)GetOrderStatus只读,不产生状态变化

典型使用场景

  • 跨聚合协作:订单提交后触发库存预留与积分累计
  • 跨上下文集成:把领域事件转换为集成事件发布给下游
  • 审计与追溯:事件序列构成完整业务轨迹,便于复盘
  • 异步解耦:把通知、报表等非核心动作从主链路移出
  • 流程驱动:用事件触发 Saga 的下一步或补偿动作
  • 数据同步:订阅事件维护搜索索引与读模型
事件发布常见两种方式:事务内写入事件表再异步投递(可靠性高),或提交后直接发消息(实现简单但可能丢事件),选型取决于一致性要求。
事件是已发生的事实,发布后不应撤回;需要纠正时通过新的补偿事件表达,而不是修改历史事件。

易错点

  • 把命令当事件发布(事件名用祈使句),下游误以为事实已发生
  • 事件在事务提交前对外发送,事务回滚后下游已开始处理,状态分叉
  • 事件 schema 不带版本,字段变更直接打断下游消费
  • 事件载荷携带整个聚合对象,下游强耦合于内部结构,任何字段调整都是破坏性变更
  • 缺少事件去重,重投递导致重复扣减或重复发券

数据来源与参考

  • Eric Evans《Domain-Driven Design》
  • Vaughn Vernon《Implementing Domain-Driven Design》
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌