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

当 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​ 模式来保证数据一致性,具体选择取决于业务对一致性的要求、性能要求和开发维护成本。

相关推荐
XDHCOM21 小时前
ORA-32484重复列名错误,ORACLE数据库CYCLE子句故障修复与远程处理方案
数据库·oracle
云烟成雨TD21 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
行乾21 小时前
鸿蒙端 IMSDK 架构探索
架构·harmonyos
于慨21 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz21 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
swg32132121 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
翻斗包菜21 小时前
PostgreSQL 日常维护完全指南:从基础操作到高级运维
运维·数据库·postgresql
gelald1 天前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川1 天前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java
呆瑜nuage1 天前
MySQL表约束详解:8大核心约束实战指南
数据库·mysql