分布式事务解决方案总结:本地消息异步确认、可靠消息最终一致性、最大努力通知

❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」
☠博主专栏 : <源码解读> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基

分布式系统中事务是一个重要挑战,先从 从实现原理、技术细节、适用场景三个维度,对三种主流分布式事务解决方案进行简单总结。

一、本地消息异步确认方案

实现原理
该方案通过「本地事务+消息表」机制实现最终一致性,核心思想是将业务操作与消息发送绑定在同一个本地事务中。具体流程如下:

  1. 消息记录:在业务数据库中创建消息表,业务操作与消息插入通过本地事务保证原子性。
  2. 异步投递:通过定时任务扫描消息表,将待发送消息投递至消息队列(如Kafka)。
  3. 状态确认:消息消费成功后,更新消息表状态;若投递失败,通过重试机制(如指数退避)保证消息不丢失。

技术细节

  • 消息表设计:需包含消息ID、业务ID、内容、状态(待发送/已发送/失败)、重试次数等字段。
  • 幂等性处理:消费端需通过业务ID去重,避免重复消费导致数据异常。
  • 性能优化:批量发送消息、独立消息库、重试次数阈值(如超过3次转入人工处理)。

适用场景

  • 订单创建与库存扣减的异步解耦。
  • 对实时性要求不高,但需严格保证数据最终一致性的业务。
二、可靠消息最终一致性方案

实现原理
基于消息队列的「半消息」机制,通过事务消息确保本地事务与消息发送的原子性。以RocketMQ为例:

  1. 半消息发送:生产者发送半消息(状态不可见)至MQ,MQ持久化后返回确认。
  2. 本地事务执行:生产者执行本地事务(如扣款),根据结果提交或回滚半消息。
  3. 消息投递:MQ根据事务结果投递消息,消费者处理业务后返回ACK确认。
  4. 事务回查:若生产者未返回明确结果,MQ通过回查接口确认事务状态。

技术细节

  • 事务消息接口:需实现executeLocalTransaction(执行本地事务)和checkLocalTransaction(事务回查)方法。
  • 消息状态机:半消息(Prepared)→ 提交(Commit)→ 消费(Consumed)或回滚(Rollback)。
  • 高可用设计:MQ的Broker集群、主从复制保障消息不丢失。

适用场景

  • 电商支付与订单状态的强一致性场景。
  • 跨系统数据同步(如用户积分与账户余额变更)。
三、最大努力通知方案

实现原理
以「重试+补偿」机制实现最终一致性,核心是主动方通过多次尝试通知被动方,直至达到最大重试次数或人工干预。流程如下:

  1. 业务处理:主动方完成本地事务(如支付成功)。
  2. 通知发送:通过HTTP/MQ发送通知,记录通知日志(含唯一ID)。
  3. 重试机制:按策略(如指数退避、固定间隔)重试,超时后转入死信队列。
  4. 被动方处理:接收通知后校验幂等性,失败时通过查询接口主动拉取数据。

技术细节

  • 通知接口设计:需支持幂等(如通过唯一ID去重)、超时重试、失败告警。
  • 补偿机制:被动方提供查询接口,主动方定期拉取未确认通知。
  • 人工干预:超限后生成工单,由运维手动处理。

适用场景

  • 第三方支付回调(如微信支付重试24小时)。
  • 物流状态更新、短信通知等非核心链路。
方案对比与选型建议
方案 一致性强度 实现复杂度 适用场景 典型问题
本地消息异步确认 最终一致 ★☆ 订单与库存解耦 消息延迟、数据库压力
可靠消息最终一致性 最终一致 ★★★ 支付与账户变更 消息重复、事务回查性能
最大努力通知 最终一致 ★★ 第三方回调、日志同步 通知丢失、人工介入成本

选型原则

  • 强一致性需求:优先选可靠消息方案(如金融交易)。
  • 高并发场景:本地消息表方案通过异步化提升吞吐量。
  • 跨系统交互:最大努力通知降低耦合,但需补偿机制兜底。

关注公众号获取更多技术干货 !

你可能感兴趣的:(面试攻关,分布式,spring,cloud,spring,boot)