【架构实战】分布式事务解决方案

一、分布式事务的挑战

在微服务架构下,一个业务操作可能涉及多个服务的数据修改。传统的本地事务无法保证跨服务的数据一致性。

经典场景:

复制代码
用户下单 → 订单服务扣库存 → 支付服务扣余额 → 物流服务创建运单

任何一步失败,都需要回滚之前的操作

二、CAP定理回顾

  • C(一致性):所有节点数据一致
  • A(可用性):每个请求都能得到响应
  • P(分区容错):网络分区时系统仍能工作

三者只能满足其二,分布式系统必须选择CP或AP。

三、主流解决方案

方案1:2PC(两阶段提交)

复制代码
阶段1:Prepare(准备)
  协调者 → 所有参与者:准备提交?
  参与者 → 协调者:准备就绪 ✓/✗

阶段2:Commit/Rollback(提交/回滚)
  全部就绪 → Commit
  任一失败 → Rollback

优点 :强一致性
缺点:同步阻塞,性能差,单点故障

方案2:TCC(Try-Confirm-Cancel)

java 复制代码
// Try:预留资源
public boolean tryDeduct(String userId, BigDecimal amount) {
    Account account = accountMapper.selectById(userId);
    if (account.getFrozen().add(amount).compareTo(account.getBalance()) > 0) {
        return false;
    }
    accountMapper.freeze(userId, amount);
    return true;
}

// Confirm:确认提交
public void confirmDeduct(String userId, BigDecimal amount) {
    accountMapper.deduct(userId, amount);
}

// Cancel:取消回滚
public void cancelDeduct(String userId, BigDecimal amount) {
    accountMapper.unfreeze(userId, amount);
}

优点 :性能好,无锁
缺点:业务侵入性强,需实现三个接口

方案3:Saga模式

复制代码
T1 → T2 → T3 → T4
↓    ↓    ↓    ↓
C1 ← C2 ← C3 ← C4  (补偿操作)

正向操作链 + 补偿操作链
java 复制代码
// Saga编排器
public class OrderSaga {
    
    public void execute(Order order) {
        try {
            orderService.create(order);
            inventoryService.deduct(order);
            paymentService.pay(order);
            shippingService.create(order);
        } catch (Exception e) {
            // 按相反顺序补偿
            shippingService.cancel(order);
            paymentService.refund(order);
            inventoryService.restore(order);
            orderService.cancel(order);
        }
    }
}

方案4:可靠消息最终一致性

java 复制代码
// 本地消息表
@Transactional
public void createOrder(Order order) {
    orderMapper.insert(order);
    
    // 同一事务中写入本地消息表
    localMessageMapper.insert(new LocalMessage(
        order.getId(), "ORDER_CREATED", order.toString()
    ));
}

// 定时任务扫描消息表,投递到MQ
@Scheduled(fixedRate = 5000)
public void scanAndSend() {
    List messages = localMessageMapper
        .selectUnsentList();
    for (LocalMessage msg : messages) {
        try {
            mqTemplate.send(msg.getTopic(), msg.getContent());
            msg.setStatus("SENT");
            localMessageMapper.updateById(msg);
        } catch (Exception e) {
            log.error("消息投递失败", e);
        }
    }
}

四、Seata框架实战

yaml 复制代码
# Seata Server配置
seata:
  enabled: true
  application-id: order-service
  tx-service-group: my_tx_group
  service:
    vgroup-mapping:
      my_tx_group: default
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
java 复制代码
// 使用@GlobalTransactional注解
@Service
public class OrderService {
    
    @Autowired
    private InventoryClient inventoryClient;
    
    @Autowired
    private PaymentClient paymentClient;
    
    @GlobalTransactional(name = "create-order", timeoutMills = 30000)
    public Order createOrder(OrderRequest request) {
        // 1. 创建订单
        Order order = orderMapper.insert(request);
        
        // 2. 扣减库存(远程调用)
        inventoryClient.deduct(request.getProductId(), request.getQuantity());
        
        // 3. 创建支付单(远程调用)
        paymentClient.create(order.getId(), request.getAmount());
        
        return order;
    }
}

五、方案对比与选型

方案 一致性 性能 复杂度 适用场景
2PC 强一致 传统数据库
TCC 最终一致 资金类业务
Saga 最终一致 长流程业务
可靠消息 最终一致 异步场景

选型建议

  • 强一致性要求:TCC
  • 最终一致性可接受:Saga 或 可靠消息
  • 简单场景:本地消息表
  • 对性能要求高:Saga

六、常见问题

Q1:空回滚怎么办?

A:记录事务状态,执行Cancel前检查是否已执行Try

Q2:悬挂问题?

A:通过全局事务ID关联,保证幂等性

Q3:补偿操作也失败了?

A:引入重试机制 + 人工干预兜底

七、总结

分布式事务没有银弹,需要根据业务特点选择合适方案:

  • 核心原则:BASE理论(基本可用、软状态、最终一致)
  • 设计思路:宁可补偿,不可阻塞
  • 工程实践:幂等性是基础,重试是保障

思考题:你的项目中如何处理分布式事务?有没有遇到过数据不一致的问题?


个人观点,仅供参考

相关推荐
老实巴交的麻匪2 小时前
Exception异常架构设计:系统性异常处理的思维革命(05)
运维·云原生·架构
FeBaby3 小时前
Java 高并发场景下 Redis 分布式锁(UUID+Lua)最佳实践
java·redis·分布式
身如柳絮随风扬3 小时前
链路追踪SkyWalking 架构了解
架构·skywalking
木泽八3 小时前
分布式系统架构模式精讲:CQRS、Saga与数据库选型完全指南
数据库·架构
金融Tech趋势派4 小时前
从OpenClaw到Hermes:AI Agent架构演进与企业落地实践深度解析
人工智能·架构·github·openclaw·hermes agent
gyx_这个杀手不太冷静4 小时前
大人工智能时代下前端界面全新开发模式的思考(五)
前端·架构·ai编程
小程故事多_804 小时前
深度拆解Hermes Agent,动态Prompt与Learning Loop架构的底层逻辑
人工智能·架构·prompt·aigc
预知同行4 小时前
深度解析 MCP 协议:架构设计与生产级安全实践
架构
studyForMokey5 小时前
【Android面试】架构模式专题
android·面试·架构
richard_yuu5 小时前
工控场景落地|分布式协调与动态重配置管理,如何实现产线不停机升级?
分布式