分布式事务 之 两阶段提交(2PC)
分布式事务 之 两阶段提交(2PC)
1、简介
XA协议
是一个基于数据库的分布式事务协议,其分为两部分:事务管理器(协调者/TC)
和本地资源管理器(参与者/RM)
。事务管理器
作为一个全局的调度者,负责对各个本地资源管理器统一号令提交
或者回滚
。二阶提交协议(2PC
)和三阶提交协议(3PC
)就是根据此协议衍生出来而来。如今Oracle
、Mysql
等数据库均已实现了XA接口
。两阶段提交
顾名思义就是要进行两个阶段的提交:第一阶段,准备阶段(投票阶段) ; 第二阶段,提交阶段(执行阶段)。
2、阶段一(投票阶段)
各参与者(Cohort)投票表明是否要继续执行接下来的事务提交操作:
- 协调者(TC)节点向所有参与者(RM)节点询问是否可以执行提交操作,并开始等待各参与者(RM)节点的响应。
- 参与者(RM)节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。
- 各参与者(RM)节点响应协调者(TC)节点发起的询问。如果参与者(RM)节点的事务操作实际执行成功,则它返回一个"同意"消息;如果参与者(RM)节点的事务操作实际执行失败,则它返回一个"中止"消息。
3、阶段二(提交执行阶段)
协调者(TC)会根据参与者(RM)的反馈情况来决定是否可以进行事务提交操作,可分为事务提交以及事务回滚两种情况 。
3.1、事务提交:
当协调者(TC)节点从所有参与者(RM)节点获得的对应的消息都为"Yes"时:
- 协调者(TC)节点向所有参与者(RM)节点发出"Commit"的请求。
- 参与者(RM)节点收到Commit请求后,正式执行事务操作,并释放在整个事务期间内占用的资源。
- 参与者(RM)节点向协调者(TC)节点发送"Ack"消息,确认完成。
- 协调者(TC)节点收到所有参与者(RM)节点反馈的"Ack"完成消息后,完成事务。

3.2、事务回滚:
如果任一参与者(RM)节点在第一阶段返回的响应消息为"No",或者协调者(TC)节点在第一阶段的询问超时之前无法获取所有参与者(Cohort)节点的响应消息时:
- 协调者(TC)节点向所有参与者(RM)节点发出"Rollback"请求。
- 参与者(RM)节点接收到"Rollback"请求,利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。
- 参与者(RM)节点向协调者(TC)节点发送"Ack"回滚完成消息。
- 协调者(TC)节点收到所有参与者(RM)节点反馈的"Ack"回滚完成消息后,取消事务。
4、两段提交(2PC)的缺点
二阶段提交看似能够提供原子性的操作,但它存在着严重的缺陷
-
同步阻塞问题:执行过程中,所有参与者节点都是事务阻塞型。各个参与者在等待其他参与者响应的过程中,将无法进行其他任务操作;
-
单点故障:由于协调者(TC)的重要性,一旦协调者(TC)发生故障,参与者(RM)会一直阻塞下去。特别是在阶段二中,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。
-
数据不一致:在阶段二中,当协调者(TC)向参与者(RM)发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者出现问题,将导致只有一部分参与者收到commit请求,以至于这部分参与者接到commit请求之后就会执行commit操作,而其他部分未接到commit请求的参与者则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。