事务协调者(PM) , 事务参与者(TM)

 

两阶段提交分为

1. 准备(prepare)

  pm发消息询问所有TM是否都准备好:

    各个tm做本地事务的预操作(如写日志),不提交

   回复pm 1. yes:准备好了   2. no: 没准备好

 

 2.提交(commit)

  tm:  

    根据yes或者no,发消息通知所有tm执行提交事务或者回滚事务,然后tm回复ack

 

分布式事务结束

 

做一个比较:

TCC(Try-Confirm-Cancel)

  1. Try:执行预操作,保留资源,但不提交。
  2. Confirm:所有参与者确认预操作,进行实际提交。
  3. Cancel:如果任何参与者未准备好,则执行补偿操作,撤销之前的预操作。

两阶段提交(2PC)

  1. Prepare:协调者询问所有参与者是否准备好,参与者执行预操作并返回状态(是或否)。
  2. Commit:根据参与者的回复,协调者决定:
    • 如果所有参与者都准备好,发送提交指令。
    • 如果有参与者不准备,发送回滚指令。

 

 

 

下面是mysql两阶段提交的场景

 

1. Prepare 阶段

在这个阶段,MySQL 执行以下操作:

  • 写入 XID:将内部 XA 事务的 ID(XID)写入 redo log,记录下该事务的标识。
  • 设置状态为 Prepare:在 redo log 中将该事务的状态设置为 "prepare",表示事务已准备好,可以进行提交。
  • 持久化到磁盘:确保 redo log 已经被写入到磁盘,确保在系统崩溃时能够恢复该事务的状态。

2. Commit 阶段

在准备阶段之后,如果所有参与者都反馈可以提交,MySQL 进入 commit 阶段,执行以下操作:

  • 写入 XID 到 binlog:将该事务的 XID 写入 binlog,记录下该事务的提交信息。
  • 持久化 binlog 到磁盘:确保 binlog 已经被写入到磁盘,确保数据的持久性和可恢复性。
  • 更新 redo log 状态:将 redo log 中该事务的状态设置为 "commit",表示该事务已经成功提交。

3. 提交标识

在 MySQL 中,事务的提交成功是以 binlog 中的 XID 写入成功作为标识:

崩溃重启后,mysql 查找 prepare 状态redo_log,在binlog中查找XID

  • 如果 binlog 中没有当前 XA 事务的 XID:则表示事务未成功提交,MySQL 会进行回滚操作,撤销该事务的所有变更。
  • 如果 binlog 中有当前 XA 事务的 XID:则表示事务成功提交,MySQL 会确认并保留该事务的变更。

 

 

1. 协调者 (Transaction Manager, PM)

  • 职责:在MySQL的上下文中,协调者通常是数据库系统本身,负责管理和协调分布式事务的状态。
  • 工作流程
    • 准备阶段 (Prepare Phase)
      • 协调者向所有参与者(即各个数据库实例)发送准备请求。
      • 各参与者执行本地事务的预操作,通常是写入日志但不提交,并回复协调者其准备状态(是/否)。
      • 协调者将XID(事务ID)写入redo log,并将状态设置为prepare。
    • 提交阶段 (Commit Phase)
      • 协调者接收到所有参与者的准备确认后,将XID写入binlog,持久化到磁盘,并通知参与者提交事务。
      • 如果有参与者回复未准备好,协调者会请求所有参与者回滚事务。

2. 参与者 (Transaction Participants, TM)

  • 职责:参与者是具体执行操作的数据库实例,负责处理本地的事务逻辑。
  • 工作流程
    • 准备阶段
      • 每个参与者接收到协调者的准备请求后,执行本地的事务逻辑,做必要的预处理(如写入本地日志),然后返回准备状态。
    • 提交阶段
      • 如果收到协调者的提交请求,参与者将执行实际的提交操作,将变更持久化到数据库。
      • 如果收到回滚请求,参与者会撤销本地事务的变更。

 

posted on 2024-09-29 22:59  towboat  阅读(3)  评论(0编辑  收藏  举报