1、角色区分:协调者、参与者
2、事务流程:CanCommit、PreCommit、DoCommit
阶段一:CanCommit
1. 事务询问
协调者向所有参与者发送一个包含事务内容的canCommit请求,询问是否可以执行事务提交操作,并开始等待参与者的响应。
2. 各参与者向协调者反馈事务询问的响应
参与者在接收到来自协调者的canCommit请求后,正常情况下如果其自身认为可以顺利执行事务,那么就会反馈yes响应,并进入预备状态,否则反馈no响应。
阶段二:PreCommit
在阶段二中,协调者根据阶段一参与者的反馈情况来决定具体执行的操作。如果全部参与者都返回了yes响应,那么就执行事务的预提交;如果有参与者反馈no,或者出现超时,则执行中断事务。
- 执行事务的预提交
1. 发送预提交请求
协调者向所有参与者节点发出preCommit命令,并进入Prepare阶段。
2. 事务预提交
参与者收到precommit命令后,会执行事务操作,并将undo和redo信息记录到事务日志中。
3. 各参与者向协调者反馈事务预执行命令的响应
参与者成功执行了事务操作,那么就会反馈给协调者ack响应,同时等待最终的指令:commit(提交) 或 abort(中止)
- 中断事务
1. 发送中断命令
协调者,向所有参与者发出abort命令。
2. 中断事务
无论是收到协调者的abort命令,还是在等待协调者的preCommit命令时超时,参与者都会中断事务。
阶段三:DoCommit
在阶段三进行真正的事务提交操作,会存在以下两种情况:
- 执行提交
1. 发送提交请求
如果协调者收到了所有参与者的ack响应,那么他将从预提交状态转换到提交状态,并向所有参与者发送doCommit命令。
2. 事务提交
参与者收到doCommit命令后,会正式执行事务的提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
3. 反馈事务提交结束
参与者完成事务提交之后,向协调者发送ack响应。
4. 完成事务
协调者收到所有参与者的ack消息后,完成事务。
- 中断事务
在阶段二有任意一个参与者返回了no响应,或者协调者在等到超时后还是无法接收到所有参与者的响应,就会执行中断事务。
1. 发送中断命令
协调者向所有参与者发送abort命令。
2. 事务回滚
参与者在接收到abort命令后,会根据undo信息执行事务回滚操作,并在完成回滚后释放整个事务期间占用的事务资源。
3. 反馈事务回滚结果
参与者完成事务回滚后,向协调者反馈ack消息。
4. 中断事务
协调者收到所有参与者反馈的ack消息后,中断事务。
另外,还需注意的是,在进入到阶段三,可能会存在以下两种故障:
1. 协调者出现问题
2. 协调者和参与者之间出现网络故障
无论哪种情况,最终都会导致参与者在超时时间内,不能收到协调者的doCommit命令。在超时后,参与者会继续提交此事务。