当前位置: 首页 > news >正文

初识分布式事务原理

        事务是指符合ACID特性的操作就是事务,在同一个数据库中,如果要分别对表A和表B进行插入和删除操作,如果其中一个操作执行失败,可以对当前数据库进行回滚,使其回滚到执行操作前的状态,但是现有的系统架构都是基于微服务的,不同服务和操作设计不同的数据库和表,如果插入操作使用的是数据库A,删除操作使用的是数据库B,那么如果想要二者符合事务的特性,要么全部执行成功,要么全部执行失败,如果失败就要进行回滚,但是不同的数据库又不能同时回滚,因此就需要使用分布式事务。

        分布式事务 是指:一个业务操作需要跨多个独立的系统(服务、数据库、消息队列等)完成,而我们仍然希望这个操作具有像本地事务一样的特性 —— 要么全部成功,要么全部失败(原子性)

常见的分布式事务解决方案有:

1. 2PC(Two Phase Commit)(两阶段提交)

2PC是一种最传统的分布式事务协议,用于确保多个数据库、系统之间在事务上达成“一致性或回滚”,它是很多数据库和中间件(如XA和JTA)支持的底层协议。

工作流程涉及一个协调者+多个参与者

1️⃣ 预提交阶段(Prepare Phase)

- 协调者向所有参与者发送“准备提交事务吗?”请求。

- 每个参与者执行本地操作,但不提交,锁住资源。

- 每个参与者回复“准备好了(Yes)”或“失败(No)”。

2️⃣ 提交阶段(Commit Phase)

- 如果所有参与者都回复 Yes,协调者广播 “正式提交”;

→ 所有参与者提交事务,释放资源。

- 如果有任一 No,协调者广播 “回滚”;

→ 所有参与者回滚之前的操作。

两阶段提交通过先让所有参与者先在本地进行执行,但不提交,确保所有参与者执行成功再提交,因此其一致性强,适用于对一致性要求极高的常见,但是缺点是所有参与者在预提交阶段不会进行提交而是锁住资源,会阻塞数据库,并且如果协调者发生“宕机”,会导致所有参与者卡死在等待阶段。

2. TCC(Try-Confirm-Cancel)

        TCC 是一种由业务开发者控制的分布式事务模式,强调“预处理 → 确认 → 回滚”的逻辑拆解。

每个参与系统都实现三套接口:

  • Try: 预留资源(比如冻结库存)
  • Confirm: 真正提交(比如扣减库存)
  • Cancel: 失败回滚(比如解冻库存)

        其工作流程不涉及到协调者,而是先让所有参与者进行预处理,执行资源预留,如果所有的参与者都 Try 成功,则进行 Confirm ,否则则进行回滚。

1️⃣ Try 阶段:

- 各参与者尝试执行资源预留,不真正变更资源;

- 保证幂等、挂起(冻结)状态。

2️⃣ Confirm 阶段:

- 所有参与者都 Try 成功后,执行 Confirm,正式提交业务操作;

- 幂等、不可逆。

3️⃣ Cancel 阶段:

- 如果任意参与者 Try 失败,执行 Cancel 补偿;

- 清理预留资源(如解冻、释放)。

3. 事务消息(如RocketMQ事务消息)

        通过引入消息中间件的事务消息机制,将发送消息与本地事务进行绑定,来确保分布式事务的正确执行。

工作流程:

1️⃣ 发送“半消息”(Prepared Message):

- 不立刻投递,标记为暂挂状态。

2️⃣ 执行本地事务:

- 如扣款、更新数据库;

- 返回结果:成功 / 失败。

3️⃣ 通知 MQ 提交或回滚:

- 如果本地事务成功 → MQ 正式投递消息;

- 如果失败 → MQ 丢弃半消息。

4️⃣ 宕机或未知状态:

- MQ 会反查发送方:本地事务执行成功没?(checkTransaction)

        值得注意的是,如果本地事务执行成功,消费者会消费到投递的消息,但是如果该消息执行失败,不会导致上游已提交的状态进行回滚,因为该操作的正确有效执行是下游业务需要保证的,不属于上游业务需要考虑的范畴,事务消息只是确保如果本地事务执行失败,则下游业务就不会获取到该条业务消息,只有执行成功的时候才能获取该条业务消息,只有投递的消息是否执行成功,是下游方需要考虑的。

http://www.xdnf.cn/news/96769.html

相关文章:

  • VMware中CentOS 7虚拟机设置固定IP(NAT模式)完整教程
  • Scanpy可视化技巧--UMAP图优化
  • 数据的加载与保存
  • 基于Quill的文档编辑器开发日志(上)——前端核心功能实现与本地存储管理
  • Java 环境配置详解(Windows、macOS、Linux)
  • 新书推荐——《游·思——看世界 上》孔祥超 著
  • 【MQ篇】RabbitMQ之工作队列模式!
  • Kotlin中实现静态
  • 智能文档解析系统架构师角色定义
  • 链表系列一>两数相加
  • 如何将 Azure Active Directory (Azure AD) 作为 SAML IdP 对接到 Keycloak
  • 从零手写 RPC-version1
  • django软件开发招聘数据分析与可视化系统设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
  • 搭建Stable Diffusion图像生成系统实现通过网址访问(Ngrok+Flask实现项目系统公网测试,轻量易部署)
  • JavaEE学习笔记(第二课)
  • C#开发usb hid 简易GUI调试工具记录
  • 2025山东省职业院校技能大赛网络安全赛项样题
  • rk3588 驱动开发(二)第四章嵌入式 Linux LED 驱动开发实验
  • 初阶数据结构--排序算法(全解析!!!)
  • 【JVS更新日志】物联网、智能BI、智能APS 4.23更新说明!
  • Android仿今日头条Kotlin版本
  • gem5教程第五章 了解gem5默认配置脚本
  • eplan许可证与防火墙安全软件冲突
  • MobileNetV2:面向移动端的高效神经网络架构革新——突破轻量化模型的设计边界
  • 三目云台转动性能稳定性
  • C# 中的 `lock` 关键字本质
  • 3.6/Q1,GBD数据库最新文章解读
  • 鸿蒙中的并发线程间通信、线程间通信对象
  • 【计算机视觉】CV项目实战- SiamMask 单阶段分割跟踪器
  • 深入理解 java synchronized 关键字