微服务中如何保证数据一致性?

当 A、B、C、D 四个微服务都涉及更新或插入 (写操作)时,由于每个服务有自己的独立数据库,传统的单机事务无法覆盖多个数据库,因此必须采用分布式事务方案来保证数据一致性。

下面我按常见的分布式事务模式来分析,并给出适用场景与示例。


1. 问题分析

  • 场景:一次业务请求需要依次或并行调用 A、B、C、D 四个服务,每个服务在自己的数据库中做增删改操作。
  • 目标 :保证这四个操作要么全部成功 ,要么全部失败(原子性),并且在发生故障时能正确恢复或补偿。
  • 挑战:网络不可靠、服务可能宕机、部分成功部分失败会导致数据不一致。

2. 分布式事务解决方案

2.1 两阶段提交(2PC, Two-Phase Commit)

  • 原理 :

    1. 准备阶段:事务协调者询问所有参与者(A、B、C、D)是否可以提交,参与者锁定资源并返回"就绪"。
    2. 提交阶段:如果所有参与者都就绪,协调者发送提交命令;否则发送回滚命令。
  • 优点:强一致性。

  • 缺点 :

    • 同步阻塞,性能差。
    • 协调者单点故障风险。
    • 在微服务+多数据库场景下实现复杂,现代应用较少使用(尤其互联网高并发场景)。

适用:传统企业级应用,对一致性要求极高,并发量不大。


2.2 三阶段提交(3PC)

  • 在 2PC 基础上引入超时机制和预提交阶段,减少阻塞范围,但依然有协调者单点问题和复杂度,实际很少用。

2.3 Saga 模式

  • 原理:将一个长事务拆分为多个本地短事务,每个本地事务完成后发布事件触发下一个本地事务;如果某个本地事务失败,则按相反顺序执行补偿事务(Compensating Transaction)来撤销之前的操作。

  • 两种实现方式:

    1. 编排式(Orchestration):由一个中心协调器(Saga Orchestrator)按顺序调用各服务的本地事务/补偿操作。
    2. 协同式(Choreography):每个服务监听事件,自己决定下一步动作,无中心协调器。
  • 优点:

    • 避免全局锁,性能好,适合微服务。
    • 最终一致性。
  • 缺点:

    • 不保证隔离性(可能出现脏写)。
    • 补偿逻辑复杂,有时难以实现(例如物理删除难以补偿)。
  • 适用:高并发互联网微服务,可接受最终一致性。

示例(编排式 Saga)

业务:创建订单 → 扣库存 → 扣余额 → 记录物流

  • 步骤 1:订单服务创建订单(本地事务)
  • 步骤 2:库存服务扣库存(本地事务)
  • 步骤 3:账户服务扣余额(本地事务)
  • 步骤 4:物流服务生成运单(本地事务)
    若步骤 3 失败,则依次执行:
  • 补偿步骤 2:库存服务恢复库存
  • 补偿步骤 1:订单服务取消订单

2.4 TCC 模式(Try-Confirm-Cancel)

  • 原理:将每个服务的方法分为三个阶段:

    1. Try:预留业务资源(如冻结库存、预扣金额)。
    2. Confirm:确认执行业务操作,使用 Try 阶段预留的资源。
    3. Cancel:取消操作,释放 Try 阶段预留的资源。
  • 优点:

    • 比 Saga 更可控,可实现类似强一致的效果(通过预留资源)。
    • 避免长期资源锁定。
  • 缺点:

    • 每个业务都要实现 Try/Confirm/Cancel 接口,开发复杂。
    • 对业务侵入性强。
  • 适用:核心金融业务(支付、交易),对一致性要求高且资源可预留。

示例

订单服务:

  • Try:检查并锁定订单状态为"处理中"
  • Confirm:更新为"已确认"
  • Cancel:更新为"已取消"
    库存服务:
  • Try:冻结相应库存
  • Confirm:扣减冻结库存
  • Cancel:解冻库存

2.5 本地消息表(可靠事件模式)

  • 原理:

    1. 业务执行时,将事件写入本地数据库的消息表(与业务操作在同一事务中)。
    2. 后台任务轮询消息表,将未发送的事件发送到消息队列。
    3. 消费者服务收到消息后执行本地事务,并确认消息。
    4. 如果消费失败,重试或进入死信队列人工处理。
  • 优点:实现相对简单,避免分布式事务框架。

  • 缺点:有数据不一致窗口,依赖消息队列可靠性。

  • 适用:异步场景,允许短暂不一致。


2.6 最大努力通知

  • 类似本地消息表,但不保证一定成功,通过多次重试尽可能达到最终一致,常用于外部系统交互(如支付回调)。

3. 方案选型建议

方案 一致性强度 性能 复杂度 适用场景
2PC 强一致 传统企业应用,低并发
Saga 最终一致 微服务主流,高并发
TCC 接近强一致 金融核心业务
本地消息表 最终一致 中低 异步、解耦场景

4. 实践建议

  1. 业务分析:先判断能否将操作合并到更少的服务(减少跨服务事务)。
  2. 降低一致性要求:很多业务可接受最终一致性,用 Saga 或消息表即可。
  3. 幂等设计:所有参与服务必须实现幂等,防止重复执行。
  4. 补偿/回滚设计:提前考虑如何撤销操作(逻辑删除、状态回滚、反向操作)。
  5. 监控与重试:完善的日志、监控、告警与重试机制。
  6. 测试:模拟各种失败场景(网络超时、服务宕机)验证一致性保障。

总结

当 A、B、C、D 都是写操作时,推荐使用 ​Saga ​ 或 ​TCC​ 模式来保证数据一致性,具体选择取决于业务对一致性的要求、性能要求和开发维护成本。

相关推荐
萧曵 丶19 小时前
Next-Key Lock、记录锁、间隙锁浅谈
数据库·sql·mysql·mvcc·可重复读·幻读
2501_9418824820 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
jayaccc20 小时前
微前端架构实战全解析
前端·架构
華勳全栈20 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_9920 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
做cv的小昊20 小时前
【TJU】信息检索与分析课程笔记和练习(7)数据库检索—Ei
数据库·笔记·学习·全文检索
沛沛老爹20 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理
专注_每天进步一点点20 小时前
【java开发】写接口文档的札记
java·开发语言
代码方舟20 小时前
Java企业级实战:对接天远名下车辆数量查询API构建自动化风控中台
java·大数据·开发语言·自动化
roman_日积跬步-终至千里20 小时前
【大数据架构-数据中台(2)】数据中台建设与架构:从战略到落地的完整方法论
大数据·架构