文章目录

  • 分布式事务(2PC、3PC、TCC、基于消息达到最终一致性)
    • 二阶段提交(2PC)
    • 三阶段提交(3PC)
    • TCC(Try-Confirm-Cancel)
    • RocketMQ基于消息达到最终一致性
    • 总结

分布式事务(2PC、3PC、TCC、基于消息达到最终一致性)

关注可以查看更多粉丝专享blog~

二阶段提交(2PC)

  • 第一阶段:请求/表决阶段

    • 在分布式事务发起者向分布式事务协调者发送请求的时候,事务协调者向所有参与者发送事务预处理请求(vote request)
    • 这个时候参与者会开启本地事务并开始执行本地事务,执行完成后不会commit,而是向事务协调者报告是否可以处理本次事务
  • 第二阶段:提交/执行/回滚阶段
    • 分布式事务协调者收到所有参与者反馈后,所有参与者节点均响应可以提交,则通知参与者和发起者执行commit,否则rollback

三点常见问题:

  1. 性能问题:从流程上面可以看出,最大的缺点就是在执行过程中节点都处于阻塞状态。各个操作数据库的节点都占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知进行全局commit/rollback,参与者进行本地事务commit/rollback之后才会释放资源,对性能影响较大。
  2. 单点故障问题:事务协调者是整个分布式事务的核心,一旦事务协调者出现故障,会导致参与者收不到commit/rollback的通知,从而导致参与者节点一直处于事务无法完成的中间状态。
  3. 消息丢失问题:在第二阶段的时候,如果发生局部网络问题,一部分事务参与者收不到commit/rollback消息,那么就会导致节点间数据不一致。

三阶段提交(3PC)

在2PC的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者指定时间没有收到协调者的commit/rollback指令,就会自动本地commit,这样可以解决协调者单点故障的问题。

  • CanCommit阶段(提交询问)

    • 分布式事务协调者询问所有参与者是否可以进行事务操作,参与者根据自身健康情况,是否可以执行事务操作响应Y/N。
  • PreCommit阶段(预提交)
    • 如果参与者返回的都是同意,协调者则向所有参与者发送预提交请求,并进入prepared阶段。
    • 参与者收到预提交请求后,执行事务操作,并保存Undo和Redo信息到事务日志中。
    • 参与者执行完本地事务之后(uncommitted),会向协调者发出Ack表示已准备好提交,并等待协调者下一步指令。
    • 如果协调者收到预提交响应为拒绝或者超时,则执行中断事务操作,通知各参与者中断事务(abort)。
    • 参与者收到中断事务(abort)或者等待超时,都会主动中断事务/直接提交。(超时情况下国内很多博客讲的是直接中断,但是wiki说的是直接提交,这里中断或提交都存在不确定性,都只有一半的概率做对,可能造成不一致情况,需要看不同框架的实现。此处需要TODO一下)

If, after a cohort member receives a preCommit message, the coordinator fails or times out, the cohort member goes forward with the commit.

  • doCommit阶段(最终提交)

    • 协调者收到所有参与者的Ack,则从预提交进入提交阶段,并向各参与者发送提交请求。
    • 参与者收到提交请求,正式提交事务(commit),并向协调者反馈提交结果Y/N。
    • 协调者收到所有反馈消息,完成分布式事务。(参与者包含事务发起者,比如A调用B,其实AB都参与了分布式事务)
    • 如果协调者超时没有收到反馈,则发送中断事务指令(abort)。
    • 参与者收到中断事务指令后,利用事务日志进行rollback。
    • 参与者反馈回滚结果,协调者接收反馈结果或者超时,完成中断事务。

TCC(Try-Confirm-Cancel)

  • Try

    • 做业务检查及资源预留(比如冻结库存,而不是直接减库存)。
  • Confirm
    • 确认提交,在Try阶段所有事务参与者执行成功之后开始执行Confirm,通常情况下,TCC默认Confirm是不会出错的,认为只要Try成功,则Confirm一定成功,若Confirm真的出错了,需要采用重试机制或者人工干预。
  • Cancel
    • 执行回滚,在Try阶段有事务参与者执行失败则开始执行Cancel,通常情况下,TCC默认Cancel是不会出错的,认为只要Try成功,则Cancel一定成功,若Cancel真的出错了,需要采用重试机制或者人工干预。

优缺点:

  1. 优点:解决了性能问题,不阻塞,不占用数据库资源。
  2. 缺点:代码入侵强,每个事务都需要实现try,confirm和cancel,还需要保证接口幂等性,开发、维护成本高。

RocketMQ基于消息达到最终一致性

RocketMQ事务消息流程图(图片来自阿里云):
RocketMQ事务消息共有三种状态,提交状态、回滚状态和中间状态。

  1. TransactionStatus.CommitTransaction:提交事务,它允许消费者消费此消息。
  2. TransactionStatus.RollbackTransaction:回滚事务,它代表该消息将被删除,不允许被消费。
  3. TransactionStatus.Unknown:中间状态,它代表需要检查消息队列来确定状态。

执行流程:

  1. 消息发送方开启事务,发送半事务消息到RocketMQ,但是该消息只保存在commitlog中,对消费者是不可见的,没有保存到customerQueue中。
  2. 消息发送方处理完本次事务之后,进入第二阶段。
    1. 如果成功则发送commit确认消息到RocketMQ将半事务消息保存到customerQueue中,让customer进行消费。
    2. 如果失败则发送rollback消息到RocketMQ将半事务消息删除。

异常分析:

  1. 预备消息发送失败。(流程会中断,所以无影响)
  2. 预备消息发送成功,但是本地事务执行失败。(预备消息没有进入customerQueue,不会被消费到,所以无影响)
  3. 预备消息发送成功,本地事务执行成功,但是发送确认消息失败,导致消息不能进入customerQueue,消费者无法消费。(解决方案:消息回查机制)

消息回查机制:

  1. RocketMQ会定时检查commitlog中的预备消息,并回查本地业务(实现LocalTransactionChecker接口的check方法)。
  2. RocketMQ会根据回查状态决定commit到customerQueue还是rollback删除消息(解决异常2和异常3)。
  3. 为了降低代码入侵和判断的复杂度,可以单独设计一张事务(Transaction)表与具体业务解耦,会查的时候根据事务表的状态进行查询即可。

保障消费幂等性:

  1. RocketMQ中Message ID有可能出现冲突,所以建议使用业务唯一标识最为幂等性处理的依据。
  2. 在消费的时候使用redis判断消息是否消费过。

总结

强一致性分布式事务代码入侵较低,但是会阻塞,占用资源,影响性能;TCC代码和业务入侵较大;弱一致性事务异步操作就会涉及到异常情况下的回滚重试,回滚失败等。所以最后还是需要从自身业务情况触发来进行选择,以下是目前主流分布式事务实现(排名不分先后)。

  1. seata
  2. ByteTCC
  3. spring-cloud-rest-tcc
  4. hmily
  5. EasyTransaction
  6. tcc-transaction
  7. RocketMQ
    1. 阿里云RocketMQ收发事务消息
    2. 消息队列 RocketMQ 版与自建开源 RocketMQ 成本对比

Davids原理探究:分布式事务(2PC、3PC、TCC、基于消息达到最终一致性)相关推荐

  1. 分布式事务解决方案:2PC,TCC以及基于消息的最终一致性

    各种形态的分布式事务 分布式事务有多种主流形态,包括:基于消息实现的分布式事务 基于补偿实现的分布式事务 基于TCC实现的分布式事务 基于SAGA实现的分布式事务 基于2PC实现的分布式事务 这些形态 ...

  2. 分布式事务2PC和TCC有啥不同

    一. 什么是2PC 2PC即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase).提交阶段(commit phase),2是指两个阶段,P是指准备阶段,C是指提交阶段. ...

  3. 分布式事务2PC、3PC、TCC、RocketMQ事务消息方案详解与对比(详细图解)

    这篇文章将介绍分布式事务中的多种实现方案,及各种分布式事务方案的实现原理.事务执行过程.优缺点,读完这篇文章相信你会对2PC.3PC.TCC.MQ事务消息有个详细的了解 分布式事务的处理方法有哪些? ...

  4. 【分布式事务】内容较多CAP/BASE/2PC/3PC/TCC/Sega等等等等~,一次性捋清楚

    分布式事务 概述 什么是分布式事务 分布式事务就是指事务的资源分别位于分布式系统的不同节点之上的事务 分布式事务产生的原因 数据库分库分表 当业务数据量达到单库单表的极限时,就需要考虑分库分表,跨多个 ...

  5. 【分布式系统】分布式事务(2PC 3PC TCC 最终一致性)

    目录 问题场景 2PC:两阶段提交 3PC:三阶段提交 TCC(Try-Confirm-Cancel) 基于MQ的最终一致性

  6. 分布式事务2PC、3PC模型

    工作中使用最多的是本地事务,但是在对单一项目拆分为 SOA.微服务之后,就会牵扯出分布式事务场景 文章以分布式事务为主线展开说明,并且针对 2PC.3PC 算法进行详细的讲解,最后通过一个 Demo ...

  7. 分布式事务专题(四):分布式事务解决方案之TCC

    目录: 基础概念 分布式事务理论 分布式事务解决方案之2pc 分布式事务解决方案之TCC(本章) 分布式事务解决方案之可靠消息最终一致性 分布式事务解决方案之最大努力通知 分布式事务综合案例分析 4. ...

  8. 《深入理解分布式事务》第九章 可靠消息最终一致性分布式事务原理

    <深入理解分布式事务>第九章 可靠消息最终一致性分布式事务原理 文章目录 <深入理解分布式事务>第九章 可靠消息最终一致性分布式事务原理 一.基本原理 二.本地消息表 1.实现 ...

  9. 分布式事务:XA,2PC,3PC,TCC,SEATA(AT)

    一.分布式事务产生原因 1.原本的数据是单库单表存储,随着业务的不断扩大数据量不断增多,单库性能支撑不了数据的更新与访问.为了解决数据库上的瓶颈,将数据库进行水平拆分,原来一个库里的事务操作,现在变成 ...

最新文章

  1. 项目实践精解:ASP.NET应用开发
  2. python绘制中国加油_软件开发|使用 Python 为你的油箱加油
  3. 聚集索引和非聚集索引实例
  4. 1951: [Sdoi2010]古代猪文
  5. 排序算法:桶排序、计数排序、基数排序
  6. zabbix安装步骤
  7. Myeclipse学习总结(9)——MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)
  8. c语言为什么运行慢,【图片】今天写几个性能测试,为什么C语言跑得这么慢呢??【c语言吧】_百度贴吧...
  9. 微服务之服务生产与消费
  10. educoder-Hadoop开发环境搭建各关卡通关答案
  11. 免费下载网易云音乐付费歌曲及下架歌曲
  12. python文件seek函数,Python 文件操作seek()函数
  13. 转 适合wince初学者的一些 知识
  14. Python数据分析-LOL英雄画像 !
  15. BugkuCTF 秋名山老司机wp
  16. 设置border线条小于1px
  17. JavaScript中的alert
  18. 计算机主机房的消防配置,计算机机房消防安全审核标准
  19. android camera 对焦大小,Android camera2对焦设置
  20. 【Shell】在windows下编辑shell脚本

热门文章

  1. Python 如何添加注释
  2. 查看当前数据库存储引擎
  3. Python计算csv数据的算数平均值
  4. VMware安装操Windows操作系统
  5. 器件打散 617版本 cadence virtuoso layout
  6. android 百度云人脸识别
  7. css选择器优先级问题
  8. 俞敏洪:坚持下去不是因为我很坚强,而是因为我别无选择
  9. WPF教程(十)使用App.xaml
  10. 6.opencv函数--cv2.bitwise_and