一.分布式事务产生原因
1.原本的数据是单库单表存储,随着业务的不断扩大数据量不断增多,单库性能支撑不了数据的更新与访问。为了解决数据库上的瓶颈,将数据库进行水平拆分,原来一个库里的事务操作,现在变成了 跨数据库的事务操作。(多数据库
2.随着业务不断增长,将业务中不同模块服务拆分成 微服务后,同时调用多个微服务所产生的跨服务分布式事务问题。(多jvm
 
二.分布式事务中的各个概念
在学习分布式事务中会在很多的地方看到很多概念,看的也是令人一头雾水,不知道其中的关系。接下来进行全面的介绍。
首先,X/OPEN是一个组织
1.X/Open DTP模型
X/Open DTP(Distributed Transaction Process)是一个分布式事务模型。这个模型主要使用了两段提交(2PC - Two-Phase-Commit)来保证分布式事务的完整性。在这个模型里面,有三个角色:
    AP: Application,应用程序。也就是业务层。哪些操作属于一个事务,就是AP定义的。
    TM: Transaction Manager,事务管理器。接收AP的事务请求,对全局事务进行管理,管理事务分支状态,协调RM的处理,通知RM哪些操作属于哪些全局事务以及事务分支等等。这个也是整个事务调度模型的核心部分。
    RM:Resource Manager,资源管理器。一般是数据库,也可以是其他的资源管理器,如消息队列(如JMS数据源),文件系统等。
2.XA协议(XA Specification)
是X/OPEN 提出的分布式事务处理规范。XA则规范了TM与RM之间的通信接口,在TM与多个RM之间形成一个双向通信桥梁,从而在多个数据库资源下保证ACID四个特性。目前知名的数据库,如Oracle, DB2,mysql等,都是实现了XA接口的,都可以作为RM。
XA是数据库的分布式事务,强一致性,在整个过程中,数据一张锁住状态,即从prepare到commit、rollback的整个过程中,TM一直把持折数据库的锁,如果有其他人要修改数据库的该条数据,就必须等待锁的释放,存在长事务风险。
以下的函数使事务管理器可以对资源管理器进行的操作:
1)xa_open,xa_close:建立和关闭与资源管理器的连接。
2)xa_start,xa_end:开始和结束一个本地事务。
3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。
4)xa_recover:回滚一个已进行预提交的事务。
5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。
6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。
 
XA各个阶段的Mysql处理流程


3.TCC
TCC是业务的分布式事务,最终一致性,不会出现长事务的锁风险,try是本地事务,锁定资源后就提交事务,confirm/cancel也是本地事务,可以直接提交事务,所以多个短事务不会出现长事务的风险。
 
三.分布式事务理论基础
1.两阶段提交(Two-phase Commit,2PC)
是XA用于在全局事务中协调多个资源的机制
顾名思义,两阶段提交在处理分布式事务时分为两个阶段:voting(投票阶段,有的地方会叫做prepare阶段)和commit阶段。
2pc中存在两个角色,事务协调者(seata、atomikos、lcn)和事务参与者,事务参与者通常是指应用的数据库。

两阶段提交协议解决的是分布式数据库数据强一致性问题
缺陷:
同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者 宕机导致的参与者处于阻塞状态的问题)
数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这会导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据不一致性的现象。
 
 
2.三阶段提交(3PC)
三阶段提交协议在协调者和参与者中都引入 超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。

三阶段提交的三个阶段分别为:can_commit,pre_commit,do_commit。

在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者abort请求时,会在等待超时之后,继续进行事务的提交。(其实这个应该是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。(一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时, 由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 )
 
2PC和3PC的区别:
相对于2PC,3PC(对2PC优化主要解决的单点故障问题,并减少阻塞, 因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。
 
3.TCC(Try-Confirm-Cancel)
Try阶段:
    完成所有业务检查(一致性),预留业务资源(准隔离性)(例如:预留资金)
Confirm阶段:
    确认执行业务操作,不做任何业务检查, 只使用Try阶段预留的业务资源。要满足幂等性。
Cancel阶段:
    取消Try阶段预留的业务资源。
TCC与XA两阶段提交有着异曲同工之妙,下图列出了二者之间的对比

1) 在阶段1:
    在XA中,各个RM准备提交各自的事务分支,事实上就是准备提交资源的更新操作(insert、delete、update等);
    而在TCC中,是主业务活动请求(try)各个从业务服务预留资源。(及时commit
2) 在阶段2:
    XA根据第一阶段每个RM是否都prepare成功,判断是要提交还是回滚。如果都prepare成功,那么就commit每个事务分支,反之则rollback每个事务分支。
    TCC中,如果在第一阶段所有业务资源都预留成功,那么confirm各个从业务服务,否则取消(cancel)所有从业务服务的资源预留请求。(及时commit

TCC两阶段提交与XA两阶段提交的区别是:
    XA是资源层面的分布式事务,强一致性阻塞式,在两阶段提交的整个过程中,一直会持有资源的锁。
       XA事务中的两阶段提交内部过程是对开发者屏蔽的,开发者从代码层面是感知不到这个过程的。而事务管理器在两阶段提交过程中,从prepare到commit/rollback过程中,资源实际上一直都是被加锁的。如果有其他人需要更新这两条记录,那么就必须等待锁释放。
    TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。
 
     TCC中的两阶段提交并没有对开发者完全屏蔽,也就是说从代码层面,开发者是可以感受到两阶段提交的存在。try、confirm/cancel在执行过程中,一般都会开启各自的本地事务,来保证方法内部业务逻辑的ACID特性。其中:
    1、try过程的本地事务,是保证资源预留的业务逻辑的正确性。
    2、confirm/cancel执行的本地事务逻辑确认/取消预留资源,以保证最终一致性,也就是所谓的补偿型事务(Compensation-Based Transactions)。由于是多个独立的本地事务,因此不会对资源一直加锁。
 
另外,这里提到confirm/cancel执行的本地事务是 补偿性事务:
补偿是一个独立的支持ACID特性的本地事务,用于在逻辑上取消服务提供者上一个ACID事务造成的影响,对于一个长事务(long-running transaction),与其实现一个巨大的分布式ACID事务,不如使用基于补偿性的方案,把每一次服务调用当做一个较短的本地ACID事务来处理,执行完就立即提交
 
4.TCC事务模型 VS DTP事务模型
比较一下TCC事务模型和DTP事务模型,如下所示:

这两张图看起来差别较大,实际上很多地方是类似的!
1、TCC模型中的主业务服务 相当于 DTP模型中的AP,TCC模型中的从业务服务 相当于 DTP模型中的RM
      在DTP模型中,应用AP操作多个资源管理器RM上的资源;而在TCC模型中,是主业务服务操作多个从业务服务上的资源。例如航班预定案例中,美团App就是主业务服务,而川航和东航就是从业务服务,主业务服务需要使用从业务服务上的机票资源。不同的是DTP模型中的资源提供者是类似于Mysql这种关系型数据库,而TCC模型中资源的提供者是其他业务服务。
2、TCC模型中,从业务服务提供的try、confirm、cancel接口 相当于 DTP模型中RM提供的prepare、commit、rollback接口
    XA协议中规定了DTP模型中定RM需要提供prepare、commit、rollback接口给TM调用,以实现两阶段提交。
    而在TCC模型中,从业务服务相当于RM,提供了类似的try、confirm、cancel接口。
3、事务管理器
     DTP模型和TCC模型中都有一个事务管理器。不同的是:
     在DTP模型中,阶段1的(prepare)和阶段2的(commit、rollback),都是由TM进行调用的。
     在TCC模型中,阶段1的try接口是主业务服务调用(绿色箭头),阶段2的(confirm、cancel接口)是事务管理器TM调用(红色箭头)。这就是 TCC 分布式事务模型的二阶段异步化功能,从业务服务的第一阶段执行成功,主业务服务就可以提交完成,然后再由事务管理器框架异步的执行各从业务服务的第二阶段。这里牺牲了一定的隔离性和一致性的,但是提高了长事务的可用性。

4.SEATA-AT

AT 模式是增强型2pc模式。

工作机制:

一阶段:

1.解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where name = 'TXC')等相关的信息。

2.查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。

3.执行业务 SQL:执行业务更新SQL。

4.查询后镜像:根据前镜像的结果,通过 主键 定位数据。

5.插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。

6.提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁

7.本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。

8.将本地事务提交的结果上报给 TC。

一阶段在分支事务提交前向TC注册分支,进行一次通信。

二阶段-回滚:

1.收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。

2.通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。

3.数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。

4.根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句。

5.提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

二阶段-提交:

1.收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。

2.异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录

全局锁

简单来说就是为了能够保证其他事务在当前事务还未释放全局锁时无法修改同一数值,实现了写的隔离.整个过程 全局锁 在当前全局事务结束前一直是被全局事物持有的,所以不会发生 脏写 的问题。

相比于传统XA(2PC)

优点

其实这些也都是XA协议(传统2PC)的缺点

1.速度更快:二阶段是异步提交,无需再像XA协议那样需要等所有的操作都执行完才进行提交.所谓分支事务的二阶段异步提交,其实就是异步删除undoLog。因为一阶段的时候已经提交了本地事务,所以二阶段就非常地快速。
2.高可用性:他将分布式事物中的协调者独立部署,可以实现高可用(可以开启多个seata服务),
不会发生脏读:因为整个过程 全局锁 在当前全局事务结束前一直是被自己持有的,所以不会发生 脏写 的问题。

缺点

1.高并发环境下,因为有全局锁的存在,性能可能会打折扣。例如对同一商品减库存,由于根据索引id做为条件,要等待锁释放。

分布式事务:XA,2PC,3PC,TCC,SEATA(AT)相关推荐

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

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

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

    文章目录 分布式事务(2PC.3PC.TCC.基于消息达到最终一致性) 二阶段提交(2PC) 三阶段提交(3PC) TCC(Try-Confirm-Cancel) RocketMQ基于消息达到最终一致 ...

  3. Seata分布式事务XA与AT全面解析

    Seata 分布式事务 XA与AT Seata 是一款开源的分布式事务解决方案,star高达17300+,社区活跃度极高,致力于在微服务架构下提供高性能和简单易用的分布式事务服务. 注:本期分享借鉴于 ...

  4. 分布式事务与2PC、3PC理论详解

    事务概念 大部分情况下我们所说的事务都是数据库事务(Database Transaction),后来延时到了非关系型数据库等其他领域,事务是运行在我们数据库上的一个逻辑工作单元,运行在工作单元中的所有 ...

  5. 分布式事务XA、TCC、AT总结

    TCC和AT在第一阶段都会直接将事务提交(commit),如果需要回滚,TCC则需要在Cancel阶段自己实现一段业务逻辑来完成数据的回滚.注意,此时是写补偿sql来完成回滚保证数据的一致性. 而AT ...

  6. 详解Mysql分布式事务XA

    在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上).在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败 ...

  7. mysql xid原理_MySQL数据库分布式事务XA实现原理分析

    [IT168 技术]MySQL XA原理 MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟悉的Binlog作为协调者;外部XA用于跨多MySQL实例的分布 ...

  8. 《深入理解分布式事务》第八章 TCC 分布式事务原理

    <深入理解分布式事务>第八章 TCC 分布式事务原理 文章目录 <深入理解分布式事务>第八章 TCC 分布式事务原理 一.TCC 核心思想 二.TCC 实现原理 1.TCC 核 ...

  9. mysql xa 实现_MySQL数据库分布式事务XA的实现原理分析

    1 原理 关于MySQL数据库的分布式事务XA,分布式事务实现的原理,可见[3];关于MySQL XA的说明,可见[1][2]. MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨 ...

最新文章

  1. HDOJ-2062 :Subset sequence(DP)
  2. python 利用模板文件生成配置文件
  3. 每日一皮:当我突然有一个很棒的调试想法...
  4. thinkphp5.0 使用paginate 分页后 foreach 循环体内不能处理数据的解决办法
  5. 问题杂记,不定时更新
  6. kotlin键值对数组_Kotlin程序检查数组是否包含给定值
  7. SpringBoot 2.1.5(12)--- Spring Boot 特性上
  8. 未解决:关于下载的ipython notebook打开的时候遇到问题的解决方法: NotJSONError(“Notebook does not appear to be JSON
  9. 贴片二极管正负极如何区分
  10. gearman:从安装到python API测试
  11. 出圈!迅镭激光切割设备亮相热播剧《麓山之歌》
  12. ACL流量控制工具-- 王贝的学习笔记
  13. CPU微指令相关概念
  14. 第三周作业#183;
  15. Portapack应用开发教程(十五) APRS接收
  16. 从硬件分析推挽输出和开漏输出详细区别
  17. 利率市场化冲击传统资产负债管理 金融壹账通助力银行科技转型
  18. 手机电容触摸屏技术简介
  19. DICOM:fo-dicom之C-STORE再分析‘解决System.ObjectDisposedException异常’
  20. 执行rpm -Uvh xxxxxx.rpm, 报freely redistributed under the terms of the GNU GPL

热门文章

  1. 【104期分享】4款简约风格PPT模板免费下载
  2. 泓博医药在创业板上市:市值超过37亿元,预计全年增收不增利
  3. 福特 EPC数据采集成功
  4. Java 23种设计模式通俗理解
  5. video阿里云视频封面获取(精确的每一帧)
  6. 手机直播助手连接到服务器,帮助中心-年轻人喜爱的互动直播平台,直播帮助,直播教程,虎牙直播...
  7. sqlite主键会加速吗_胃癌化疗后三个月去世,做化疗真的会加速病情吗?来看看实际情况...
  8. 太理java题库_2020年Java题库整理
  9. 华为OJ_1960_字符串分割
  10. 【观察】VMware:二十而冠,以梦为马不负韶华