知识卡片
微服务内领域事件:事件总线与事务机制的一致性取舍
内容
DDD要求”一次事务只更新一个聚合”,因为聚合是微服务内最小的业务功能单元,聚合内数据变更要作为一个整体一次性通过仓储提交,以保证符合聚合内固定的业务规则。但如果一次业务交易确实需要同时更新微服务内多个聚合的数据,就必须在两种方案里选择:一是引入事件总线(Event Bus),发布方聚合把事件数据发布到总线,订阅方聚合接收后完成自己的更新,用异步机制实现多个聚合间的最终一致性,代价是会增加微服务开发的复杂度;二是在应用服务里加事务控制,通过事务机制组合多个聚合的领域服务、实现数据强一致性,适合对实时性和一致性要求高的场景,但事务机制本身可能带来性能损耗。这条取舍本质上是[[聚合内强一致性聚合间最终一致性一次事务只改一个聚合]]这条原则在同一个微服务内部的具体展开——即使没有跨越微服务边界,只要跨越了聚合边界,就同样面临”要不要为了强一致性支付事务开销”的选择,微服务边界不是这个权衡出现的唯一门槛,聚合边界本身就已经是门槛。
参考来源
- 位置:第9章《领域事件:解耦微服务的关键》"9.1.1 微服务内的领域事件"(源文件:_epub-src/OEBPS/Text/chapter3-5-1-1.xhtml)
- 结论依据:原文说明"按照DDD'一次事务只更新一个聚合'的原则,你可以引入事件总线(Event Bus),通过事件总线来实现微服务内多聚合数据的最终一致性,或者采用事务机制保证数据强一致性……这种方式一般应用于实时性和数据一致性要求高的业务场景,但采用事务机制可能会出现系统性能损耗",直接支撑本卡片结论。
- 原始内容:如果在一次交易中需要同时更新多个聚合数据,那么每一个聚合就是一个独立的数据提交单元……而基于事件总线的异步化机制,就可以保证微服务内聚合之间数据提交时的最终一致性。如果不采用事件总线的最终数据一致性机制,其实你也可以采用事务机制保证数据强一致性。