You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD模块化单体(modular monolith)中如何保障跨上下文一致性?

模块化单体下跨限界上下文操作的实现方案

你完全不需要用HTTP调用,这种方案把单体架构的优势全丢了,还额外引入了网络IO、序列化、请求失败等不必要的问题,以下是符合架构规范的实现思路:


1. 逻辑归属层级

跨限界上下文的协调逻辑应该放在独立的应用协调层/集成层,不要放到商务、库存、财务任何单个模块的领域层或内部应用层:

  • 三个模块各自对外暴露无状态的应用服务接口,只封装自身域内的逻辑,不感知其他模块的存在
  • 协调层仅依赖三个模块的对外接口,负责编排整个销售/采购的全流程,不需要侵入任何模块的内部实现

2. 基于Unit of Work的强一致性实现

如果你的业务要求三个操作必须同时成功/失败,且三个模块的数据库支持同一本地事务(比如同一数据库实例下的不同schema、或同一数据源的不同表),完全可以用Unit of Work模式实现强一致,实现步骤如下:

  • 定义统一的Unit of Work接口,三个模块的数据库会话都绑定到同一个UoW上下文
  • 协调层按顺序调用三个模块的业务逻辑:
    1. 调用商务模块接口创建销售/采购订单,仅将实体变更写入UoW追踪,不提交事务
    2. 调用库存模块接口扣减/增加对应商品库存,同样仅写入UoW追踪
    3. 调用财务模块接口生成应收/应付账单,写入UoW追踪
  • 所有逻辑执行无报错后,调用UoW的Commit()方法统一提交所有变更
  • 任意一步抛出异常,直接触发UoW的Rollback(),三个模块的所有变更全部回滚,不会出现一致性问题

这种方案的适用场景是业务对一致性要求极高,且三个操作都属于短平快的逻辑,不会长时间占用数据库锁资源。


3. 最终一致性实现(适合后续要拆微服务的场景)

如果三个模块用了独立的数据库实例、或某步操作耗时长不适合加锁、或业务允许短时间的状态不一致,可以用进程内事件驱动方案,比微服务的Kafka方案更轻量,同时保持低耦合:

  • 商务模块完成自身订单创建并提交本地事务后,发布一个SalesOrderCreated或PurchaseOrderCreated的领域事件
  • 库存、财务模块各自注册对应事件的监听器,接收到事件后执行自身的业务逻辑
  • 配合内置的重试队列+死信队列处理失败场景:某模块操作失败时先按固定策略重试,重试超过阈值后存入死信队列触发人工告警,保证最终一致性

这种方案的优势是完全解耦三个模块,后续如果要拆成微服务,只需要把进程内事件的发布/订阅逻辑换成消息中间件即可,业务逻辑几乎不需要改动。


避坑提醒

  • 不要在单个模块的领域逻辑里硬编码调用其他模块的接口,会导致模块强耦合,后续迭代和拆分成本极高
  • 不要引入XA之类的分布式事务方案,性能损耗大,单体架构下完全没有必要使用
  • 所有跨模块的参数传递只能用模块对外暴露的DTO,不能直接传递内部领域实体,避免模块边界被破坏

内容的提问来源于stack exchange,提问作者JsHitachi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 06:06:05