DTP学习笔记

原创
2019/04/19 16:59
阅读数 92

X/Open DTP

X/Open DTP(X/Open Distributed Transaction Processing Reference Model) 是X/Open 这个组织定义的一套分布式事务的标准。

DTP基础组件( AM3):

  • Application Program(AP) — 应用程序
  • Transaction Manager(TM) — 事务管理器
  • Resource Manager(RM) — 资源管理器
  • Communication Resource Managers(CRMs)— 通讯资源管理器

在这个模型中,通常事务管理器(TM)是交易中间件,资源管理器(RM)是数据库,通信资源管理器(CRM)是消息中间件。XA则是DTP模型定义TM和RM之前通讯的接口规范,XA接口函数由数据库厂商提供。TM交易中间件用它来通知数据库事务的开始、结束以及回滚。2PC和3PC就是根据这种思想衍生而来。

2PC

2PC,二阶段提交协议,即将事务的提交过程分为两个阶段来进行处理:准备阶段和提交阶段。事务的发起者称为协调者,事务的执行者称为参与者。

执行阶段

  • 准备提交阶段(Prepare)
  • 提交阶段(Commit/Rollback)

参与角色

  • 协调者(coordinator)
  • 参与者(participants)

执行流程

阶段1:准备阶段

  1. 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复
  2. 各参与者执行事务操作,将Undo和 Redo信息记入事务日志中(不提交事务)
  3. 如参与者执行成功,给协调者反馈 YES,即可以提交;如执行失败,给协调者反馈NO,即不可以提交

阶段2:提交阶段

此阶段分两种情况

  • 所有参与者反馈YES
  • 任意一个参与者反馈NO

提交事务[Commit](所有参与者反馈YES)

  1. 协调者向所有参与者发出正式提交事务的请求

  2. 各参与者执行提交,并释放整个事务期间占用的资源

  3. 各参与者向协调者反馈Ack完成的消息

  4. 协调者收到所有参与者反馈的Ack消息后,即完成事务提交

    示意图如下:

2pc commit

中断事务[Rollback](任意一个参与者反馈NO)

  1. 协调者向所有参与者发出回滚请求

  2. 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源

  3. 各参与者向协调者反馈Ack完成的消息

  4. 协调者收到所有参与者反馈的 Ack 消息后,即完成事务的中断

    示意图如下:

    2pc rollback

缺点

  1. 同步阻塞: 在事务执行过程中,所有参与节点都是事务阻塞型的。参与者占有公共资源时,其他第三方节点访问公共资源则会处于阻塞
  2. 单点故障:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
  3. 脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。当协调者向参与者发送Commit请求之后,发生了局部网络异常或者在发送Commit请求过程中协调者发生了故障,导致只有一部分参与者接收到了Commit。而在这部分参与者接收到Commit请求之后就会执行Commit操作。但其他未接收到Commit请求的参与者则无法执行事务提交。于是整个分布式系统化出现了数据不一致的现象。

3PC

3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、doCommit三个阶段进行处理。

与两阶段提交不同的是,三阶段提交有两个改动点:

  1. 引入超时机制。(超时提交策略,当第三阶段参与者等待协调者超时后会提交事务,解决参与者同步阻塞问题,同时能在发生单点故障时,继续达成一致)
  2. 在第一阶段和第二阶段中插入一个准备阶段。(也是为了减少同步阻塞的发生范围)

执行阶段

  • 能否提交阶段(CanCommit)
  • 预提交阶段(PreCommit)
  • 提交阶段(doCommit)

参与角色

  • 协调者(coordinator)
  • 参与者(participants)

执行流程

阶段1:CanCommit

  1. 协调者向所有开发者发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者反馈
  2. 参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入准备状态,否则反馈NO

阶段2:PreCommit

此情况分为两种情况:

  • 所有参与者均反馈YES,即执行事务预提交
  • 任何一个参与者反馈NO,或等待超时后协调者尚无法收到参与者的反馈,即执行中断事务

事务预提交

  1. 协调者向所有参与者发出PreCommit请求,进入准备阶段
  2. 参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)
  3. 各参与者向协调者反馈Ack响应或No响应,并等待最终指令

中断事务

  1. 协调者向所有参与者发出abort请求
  2. 收到协调者的abort请求或者等待超时,参与者均会中断事务

阶段3:doCommit

此情况分为两种情况:

  • 所有参与者均反馈Ack响应,即执行真正的事务提交
  • 任何一个参与者反馈NO,或等待超时后协调者尚无法收到参与者的反馈,即中断事务

提交事务(所有参与者反馈Ack响应):

  1. 如果协调者处于工作状态,则向所有参与者发出 doCommit请求
  2. 参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源
  3. 各参与者向协调者反馈Ack完成的消息
  4. 协调者收到所有参与者反馈的Ack消息后,即完成事务提交

中断事务(任何一个参与者反馈NO):

  1. 如果协调者处于工作状态,则向所有参与者发出 abort 请求

  2. 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源

  3. 各参与者向协调者反馈Ack完成的消息

  4. 协调者收到所有参与者反馈的Ack消息后,即完成事务中断

    示意图如下:

    3pc

在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。

优点

  1. 降低了阻塞范围,在等待超时后协调者或参与者中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务

缺点

  1. 脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法和参与者正常通信,会导致参与者继续提交事务,造成数据不一致
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部