news 2026/4/19 21:29:50

分布式事务: 主流最终一致性方案对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分布式事务: 主流最终一致性方案对比

分布式事务的最终一致性方案旨在确保在分布式系统中,所有参与方最终将达到一致的状态,尽管在过程中可能存在短暂的不一致。这种模型在保证系统可用性和分区容错性的同时,牺牲了强一致性的实时性要求。以下是几种主流的最终一致性方案的汇总与详解。

主流最终一致性方案对比

方案一致性模型性能实现复杂度典型适用场景核心思想
TCC最终一致金融、电商核心业务(如扣减库存)业务侵入补偿型事务,分为Try、Confirm、Cancel三个阶段。
Saga最终一致长流程、跨服务业务编排将长事务拆分为一系列本地事务,通过正向执行和反向补偿来保证最终一致。
本地消息表最终一致异步通知、对账场景利用数据库本地事务,将消息生产和业务操作绑定,通过异步轮询重试保证下游消费。
可靠消息(基于MQ)最终一致高并发、最终一致场景(如状态同步)借助消息队列的持久化、重试和确认机制,确保消息至少被成功消费一次。

方案详解与示例

1. TCC (Try-Confirm-Cancel)

TCC是一种业务侵入性较强的补偿型事务,要求每个服务提供三个接口:Try(预留资源)、Confirm(确认提交)、Cancel(取消释放)。

核心原理:在Try阶段锁定或预留必要资源,所有参与者Try成功后,在Confirm阶段提交;若任一Try失败,则在Cancel阶段执行补偿操作,释放预留资源。

适用场景:适用于对一致性要求较高且能容忍短暂资源锁定的核心业务,如电商下单时的库存扣减和优惠券核销。

代码示例(库存服务伪代码)

// 库存服务接口定义 public interface InventoryService { // Try: 预扣库存 boolean tryDeduct(Long productId, Integer quantity); // Confirm: 确认扣减 boolean confirmDeduct(Long productId, Integer quantity); // Cancel: 取消预扣,回退库存 boolean cancelDeduct(Long productId, Integer quantity); } // 实现示例 @Service public class InventoryServiceImpl implements InventoryService { @Override @Transactional public boolean tryDeduct(Long productId, Integer quantity) { // 检查并预扣库存(如将可用库存转入冻结库存) int rows = inventoryMapper.freezeStock(productId, quantity); return rows > 0; } @Override @Transactional public boolean confirmDeduct(Long productId, Integer quantity) { // 确认扣减,清除冻结记录 return inventoryMapper.confirmFreeze(productId, quantity) > 0; } @Override @Transactional public boolean cancelDeduct(Long productId, Integer quantity) { // 取消预扣,将冻结库存加回可用库存 return inventoryMapper.unfreezeStock(productId, quantity) > 0; } }

2. Saga

Saga模式将一个分布式事务拆分为一系列连续的本地事务。每个本地事务都有对应的补偿事务。执行流程中,如果某个本地事务失败,则会按相反顺序触发前面所有已成功事务的补偿操作。

适用场景:适用于业务流程长、步骤多、跨多个服务的场景,如机票酒店预订流程。

实现模式

  • 编排式:由一个中心协调器来触发并监听各个服务。
  • 协同式:每个服务完成后触发下一个服务,并知晓自己的补偿操作。

3. 本地消息表

该方案利用数据库的本地事务原子性,将消息生产和业务操作放在同一个事务中。

核心流程

  1. 业务服务在完成本地数据库操作的同时,向同一数据库的“消息表”插入一条待发送的消息记录。
  2. 有一个独立的“消息发送者”定时轮询消息表,将未发送的消息投递到消息队列。
  3. 下游消费者从MQ消费消息,处理业务,处理成功后调用回调接口或发送确认消息。
  4. 消息发送者收到确认后,将消息状态更新为“已发送”或删除。

代码示例(订单创建与消息存储)

-- 在同一事务中执行订单创建和消息记录插入 START TRANSACTION; -- 1. 创建订单 INSERT INTO `order` (order_id, user_id, amount, status) VALUES ('O001', 1001, 299.00, 'CREATED'); -- 2. 在本地消息表中记录待发送的“扣减库存”事件 INSERT INTO `outbox_message` (message_id, `topic`, payload, status, created_time) VALUES (UUID(), 'inventory.deduct', '{"orderId":"O001","productId":"P1001","quantity":1}', 'PENDING', NOW()); COMMIT;

4. 可靠消息(基于消息队列)

此方案高度依赖消息队列(如RocketMQ、Kafka)的事务消息或类似机制来保证可靠性。

核心流程(以RocketMQ事务消息为例)

  1. 发送半消息:生产者向MQ发送一个“半消息”(对消费者不可见)。
  2. 执行本地事务:生产者执行本地业务逻辑(如创建订单)。
  3. 提交或回滚:根据本地事务执行结果,向MQ发送Commit或Rollback指令。
    • Commit:半消息变为正式消息,可供消费者消费。
    • Rollback:消息被丢弃。
  4. 消费与重试:消费者消费消息并处理业务。如果消费失败,MQ会按重试策略重新投递,直到成功或进入死信队列。

配置示例(RocketMQ生产者)

// 创建事务监听器,用于执行本地事务和检查本地事务状态 TransactionListener transactionListener = new TransactionListenerImpl(); TransactionMQProducer producer = new TransactionMQProducer("please_rename_unique_group_name"); producer.setNamesrvAddr("localhost:9876"); producer.setTransactionListener(transactionListener); producer.start(); // 发送事务消息 Message msg = new Message("OrderTopic", "TagA", "OrderID001", "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET)); SendResult sendResult = producer.sendMessageInTransaction(msg, null); // 第二个参数可用于传递业务参数

方案选型建议

  • 高并发与业务复杂:优先考虑TCC,因其性能好且业务控制粒度细。
  • 简单业务,允许延迟:使用本地消息表,实现相对简单,对中间件依赖小。
  • 长流程、跨系统编排Saga模式更为合适,适合流程化的业务场景。
  • 已深度依赖消息队列:直接采用可靠消息方案,充分利用MQ的成熟能力实现最终一致。

在实际架构中,常组合使用多种方案。例如,一个电商下单系统可能:创建订单使用本地事务;扣减库存采用TCC或预扣库存;优惠券核销采用预冻结+最终扣减;而支付成功后的状态同步则通过消息队列保证最终一致性。系统必须设计完善的补偿机制,如订单超时未支付时触发库存回退和优惠券释放,并配合重试、告警等异常处理策略。


参考来源

  • 分布式事务一致性方案介绍_分布式事务处理多喝保证库存、订单、优惠券核销原子性-CSDN博客
  • 分布式事务里的最终一致性
  • 分布式事务处理与一致性保障方案详解
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 21:28:06

R语言实战:基于RMST的生存曲线差异检验在肝癌预后评估中的应用

1. 为什么需要RMST方法评估肝癌患者生存差异 第一次接触肝癌临床数据分析时,我和很多初学者一样,习惯性地使用传统风险比(HR)和Kaplan-Meier曲线来比较不同治疗方案的生存差异。直到遇到一个真实案例:两组患者的生存曲…

作者头像 李华
网站建设 2026/4/19 21:27:45

VXLAN三层网关实战:跨子网通信配置与排错指南

1. VXLAN三层网关基础概念 第一次接触VXLAN三层网关时,我也被那些专业术语搞得一头雾水。简单来说,VXLAN就像给传统网络套了个"马甲",让不同子网的设备能够像在同一个局域网里那样通信。而三层网关就是这个"马甲"的交通警…

作者头像 李华
网站建设 2026/4/19 21:25:01

若依WMS仓库管理系统:10分钟快速上手的完整实战指南

若依WMS仓库管理系统:10分钟快速上手的完整实战指南 【免费下载链接】RuoYi-WMS-VUE 若依wms是一套基于若依的wms仓库管理系统,支持lodop和网页打印入库单、出库单。包括仓库/库区/货架管理,出入库管理,客户/供应商/承运商&#x…

作者头像 李华
网站建设 2026/4/17 12:55:38

从肖臻公开课出发:深入解析比特币核心机制与实战应用

1. 比特币的密码学基础:哈希与签名 比特币系统的安全性建立在密码学基础之上,主要依赖两个核心功能:哈希函数和数字签名。哈希函数在比特币中扮演着重要角色,它具备三个关键特性:抗碰撞性(collision resist…

作者头像 李华
网站建设 2026/4/17 12:55:36

golang如何实现文件断点续传_golang文件断点续传实现实战

断点续传必须用os.O_CREATE|os.O_WRONLY打开文件并显式Seek,禁用os.O_APPEND;需结合内容哈希校验、应用层状态同步、临时文件原子提交来保障一致性。为什么 os.OpenFile 必须用 os.O_APPEND 以外的方式打开文件断点续传的核心是“从指定偏移位置继续写”…

作者头像 李华
网站建设 2026/4/17 12:53:40

如何快速掌握视频智能分析:面向初学者的完整指南

如何快速掌握视频智能分析:面向初学者的完整指南 【免费下载链接】video-analyzer Analyze videos using LLMs, Computer Vision and Automatic Speech Recognition 项目地址: https://gitcode.com/gh_mirrors/vi/video-analyzer 在视频内容呈指数级增长的今…

作者头像 李华