领域事件是什么
领域事件表示业务领域中已经发生的事实,命名用过去时并带业务语义,例如“订单已提交”“支付已完成”。它用于解耦聚合之间的协作:本聚合完成状态变更后发布事件,其他聚合或上下文订阅处理,从而在无法使用单一事务的场景下达成最终一致。领域事件面向本上下文内部;对外发布时需要转换为更稳定的集成事件,并带上版本号。
基本信息
| 命名 | 过去时加业务语义,如 OrderSubmitted、PaymentCompleted |
|---|---|
| 内容 | 事件 ID、发生时间、聚合标识与关键业务数据 |
| 与集成事件 | 领域事件面向本上下文;集成事件面向外部,更稳定且需版本化 |
| 发布时机 | 与状态变更在同一事务内写入,事务提交后再对外发送 |
| 消费要求 | 消费端幂等,事件可重投递且顺序只在同一聚合键内保证 |
命名对照
| 表达 | 示例 | 说明 |
|---|---|---|
| 命令(祈使句) | SubmitOrder | 表达意图,可能被拒绝 |
| 领域事件(过去时) | OrderSubmitted | 描述事实,已发生不可撤回 |
| 集成事件(过去时加版本) | sales.order.submitted.v1 | 对外契约,需要兼容演进 |
| 查询(问句) | GetOrderStatus | 只读,不产生状态变化 |
典型使用场景
- 跨聚合协作:订单提交后触发库存预留与积分累计
- 跨上下文集成:把领域事件转换为集成事件发布给下游
- 审计与追溯:事件序列构成完整业务轨迹,便于复盘
- 异步解耦:把通知、报表等非核心动作从主链路移出
- 流程驱动:用事件触发 Saga 的下一步或补偿动作
- 数据同步:订阅事件维护搜索索引与读模型
事件发布常见两种方式:事务内写入事件表再异步投递(可靠性高),或提交后直接发消息(实现简单但可能丢事件),选型取决于一致性要求。
事件是已发生的事实,发布后不应撤回;需要纠正时通过新的补偿事件表达,而不是修改历史事件。