分布式事务------XA协议/2PC(Seata AT)

·XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。

·XA 规范 使用两阶段提交(2PC,Two-Phase Commit)协议来保证所有资源同时提交或回滚任何特定的事务。

分布式事务------XA协议/2PC(Seata AT)_第1张图片

角色说明:

·AP 应用程序,也就是业务层。哪些操作属于一个事务,AP来定义。

·RM 资源管理器。一般是数据库,也可以是消息队列,文件系统等。

·TM 事务管理器,接收AP的事务请求,对全局事务进行管理,管理事务的状态,协调RM的处理,通知RM哪些操作属于哪些全局事务以及事务分支等等。

AP自己操作TM,当需要事务时,AP向TM请求发起事务,TM负责整个事务的提交,回滚

分布式事务------XA协议/2PC(Seata AT)_第2张图片

2pc解决的是分布式数据强一致性问题

分布式事务------XA协议/2PC(Seata AT)_第3张图片

优点:

实现原理简单。

缺点:

  1. 性能问题:

2PC的提交在执行过程中,所有参与事务操作的逻辑都处于阻塞状态,也就是说,各个参与者都在等待其他参与者响应,无法进行其他操作;

  1. 数据不一致问题

数据不一致。当执行事务提交过程中,如果协调者向所有参与者发送Commit请求后,发生局部网络异常或者协调者在尚未发送完Commit请求,即出现崩溃,最终导致只有部分参与者收到、执行请求。于是整个系统将会出现数据不一致的情形;

  1. 协调者单点故障问题

事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,会导致参与者收不到提交或回滚的通知,从而导致参与者节点始终处于事务无法完成的中间状态。

3PC

作为2PC的改进版,3PC将原有的两阶段过程,重新划分为CanCommitPreCommitdo Commit三个阶段,引入超时机制

分布式事务------XA协议/2PC(Seata AT)_第4张图片

分布式事务------XA协议/2PC(Seata AT)_第5张图片在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者abort请求时,会在等待超时之后,继续进行事务的提交。(其实这个应该是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。(一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时, 由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 )

2PC和3PC的区别:

3PC在协调者和参与者中都引入超时机制2PC只有协调者才有超时机制。

好处:

避免了参与者在长时间无法与协调者节点通讯(协调者挂断)的情况下,无法释放资源。

缺点:

没有解决数据不一致问题。假如在doCommit中,参与者A无法接收协调者的通信,那么A会自动提交,但是提交失败了,其他参与者成功了,此时数据就会不一致。

Seata 中的 AT 模式

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

AT模式的角色:

·TM

·TC

协调者,管理全局事务

·RM

·undolog

·redolog

为什么要用redolog

两阶段提交协议的演变,没有一直锁表

·一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源

·二阶段:

·提交异步化,非常快速地完成

·或回滚通过一阶段的回滚日志进行反向补偿

分布式事务------XA协议/2PC(Seata AT)_第6张图片

Seata AT模式的例子

有个充值业务,现在有两个服务,一个负责管理用户的余额另外一个负责管理用户的积分

Seata AT分为两阶段,主要逻辑全部在第一阶段,第二阶段主要做回滚或日志清理的工作。

一阶段

  1. 先解析sql语句,得到表名,条件,sql类型,等信息
  2. 得到前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
  3. 执行业务 SQL
  4. 查询后镜像:根据前镜像的结果,通过 主键 定位数据。
  5. 插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。
  6. 提交前,向 TC 注册分支:申请一个主键等于目标数据主键值的全局锁 。本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交.
  7. 将本地事务提交的结果上报给 TC。

二阶段-提交

  1. 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
  2. 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。

二阶段-回滚

  1. 收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。
  2. 通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
  3. 数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。
  4. 根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句
  5. 提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

第一阶段流程:

分布式事务------XA协议/2PC(Seata AT)_第7张图片

  1. 余额中得TM向TC申请开启一个全局事务,TC会返回一个全局的事务ID。(①TC需要做什么存储记录吗?
  2. 余额服务在执行本地业务之前,RM会先向TC注册分支事务。
  3. 余额服务依次生成undo log、执行本地事务、生成redo log,最后直接提交本地事务。
  4. 余额服务的RM向TC汇报,事务状态是成功的。
  5. 余额服务发起远程调用,把事务ID传给积分服务。(余额服务先完成事务)
  6. 积分服务在执行本地业务之前,也会先向TC注册分支事务。
  7. 积分服务依次生成undolog、执行本地事务、生成redo log,最后直接提交本地事务。
  8. 积分服务的RM向TC汇报,事务成功。
  9. 积分服务返回远程调用成功给余额服务。
  10. 余额服务的TM向TC申请全局事务的提交/回滚,

第二阶段流程:

Client和TC之间是有长连接的,如果是正常全局提交,则TC通知多个RM异步清理掉本地的redo和undolog即可。如果是回滚,则TC通知每个RM回滚数据即可。

这里就会引出一个问题,由于本地事务都是自己直接提交了,后面如何回滚,由于我们在操作本地业务操作的前后,做记录了undo log和redo log,因此可以通过undo log进行回滚

由于undolog和redo log和业务操作在同一个事务中,因此肯定会同时成功或同时失败。

注意:undo log是被修改前的数据,可以用于回滚;reod log是被修改后的数据,用于回滚校验。

全局锁

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

相比于传统XA(2PC)

优点

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

  1. 速度更快:二阶段是异步提交,无需再像XA协议那样需要等所有的操作都执行完才进行提交.所谓分支事务的二阶段异步提交,其实就是异步删除undoLog。因为一阶段的时候已经提交了本地事务,所以二阶段就非常地快速。

  1. 高可用性:他将分布式事物中的协调者独立部署,可以实现高可用(可以开启多个seata服务),

  1. 不会发生脏读:因为整个过程 全局锁 在当前全局事务结束前一直是被自己持有的,所以不会发生 脏写 的问题。

缺点:

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

------------待完善-----------------------

你可能感兴趣的:(分布式事务,分布式,java)