Spring Boot 六边形架构下多事务资源的分布式事务如何实现?
六边形架构下多事务资源的分布式事务管理方案
核心原则:所有事务相关的基础设施实现必须完全封装在基础设施层,领域层(包括用例逻辑)只能依赖与技术无关的事务抽象,绝对不能耦合特定的事务管理器、多事务源的实现细节。
方案1:强一致事务方案(适合对原子性要求极高的业务场景)
- 首先在基础设施配置层统一实现多事务源的整合:
如果需要严格的ACID原子性,可以基于XA协议配置JtaTransactionManager,自动管理多个事务资源的二阶段提交;如果能接受最佳努力1PC的一致性,可以配置Spring的ChainedTransactionManager依次管理多个独立事务管理器的提交/回滚。 - 对领域层屏蔽实现细节:
给整合后的全局事务管理器定义一个与技术无关的别名,例如globalUseCaseTransactionManager,还可以进一步封装为自定义注解@UseCaseTransactional,元注解配置@Transactional("globalUseCaseTransactionManager"),领域层的用例方法直接使用该自定义注解即可,完全不需要感知底层存在多个事务源,也不会耦合基础设施层的具体事务实现。
改造后的用例代码示例:@Component @RequiredArgsConstructor public class MyShinyUseCase implements MyShinyPrimaryPort { private final transactionalSecondaryPort trPort1; private final anotherTransactionalSecondaryPort trPort2; @Override @UseCaseTransactional // 完全无技术耦合的事务注解 public void useCaseMethod() { trPort1.operate(); trPort2.operate(); // 任意节点报错都会触发所有事务资源的回滚,由底层封装的全局事务管理器实现 } }
方案2:最终一致事务方案(适合绝大多数允许短时间数据不一致的业务场景,性能更高)
- 基于领域事件 + 补偿机制实现原子性,完全规避分布式事务组件的依赖:
用例逻辑中仅操作第一个事务资源,操作完成后发布对应的领域事件,事务的扩散、重试、补偿逻辑全部下沉到基础设施层实现。 - 具体执行流程:
- 用例方法开启第一个资源的事务,执行业务操作,同时持久化待发布的领域事件到同库的事件表,提交事务(原子保证操作完成和事件一定被发布)
- 基础设施层的事件发布组件扫描事件表,将事件推送到消息队列
- 消息消费者(基础设施层实现)接收到事件后,执行第二个资源的操作
- 如果第二个资源操作失败,自动触发重试,重试超过阈值后触发补偿逻辑(调用第一个资源对应的回滚端口实现数据回滚),或者投递到死信队列人工兜底。
- 该方案完全符合六边形架构的依赖原则:领域层仅负责定义事件结构和发布事件的抽象接口,完全不感知事件的投递、重试、补偿逻辑,所有技术实现全部在基础设施层完成。
方案选型建议
- 涉及资金、核心数据变更的强一致要求场景,选择方案1的XA/JTA强一致实现
- 普通业务场景优先选择方案2的最终一致实现,性能更高,扩展性更好,不会受XA事务的性能损耗和资源锁定限制
内容的提问来源于stack exchange,提问作者Mr.Eddart
相关产品推荐
相关产品推荐

