1.两阶段提交(2PC):
两阶段提交协议,简称2PC(2 Prepare Commit),是比较常用的解决分布式事务问题的方式,要么所有参与进程都提交事务,要么都取消事务,即实现ACID中的原子性(A)的常用手段。2PC流程图
流程解释:
1.1 一阶段Prepare。首先是事务协调者像所有参与事务的集群发起事务的询问,询问各个参与者是否能够正常执行
1.2 各参与者收到协调者发送的询问请求后执行各自的事务,但不立即提交事务
1.3 参与者执行完各自的事务之后它会向协调者上报执行状态(要么正常执行,要么失败或等待超时)。协调者会收集所有参与者所反馈回来的状态
2.1 如果协调者收到所有参与者反馈的状态都是commit,那么就会推进到二阶段。协调者向所有的事务参与者发起事务提交通知
2.2 各事务参与者提交自己的事务
2.3 事务提交完成后,每一个参与者向事务协调者上报事务提交的结果
成功执行事务事务提交流程:
阶段一Prepare事务询问:
协调者向所有的参与者发送事务内容,询问是否可以执行事务的操作,并开始等待各参与者的响应。然后参与者向协调者反馈1阶段的请求为yes,表示可以执行事务操作。如果协调者收到所有参与者都反馈为yes就推进到2阶段。
阶段二Commit:
协调者向事务参与者都会发出一个commit请求,所有的参与者收到commit请求之后执行事务提交的操作。执行完事务提交之后就向协调者发起ACK的信息。当协调者收到所有参与者发起的ACK信息就代表事务执行成功
中断事务流程:
首先还是协调者向参与者发起事务询问,询问能否进行事务操作,此时参与者资源2由于网络超时或节点故障等原因无法执行事务操作。协调者发现收集回来的所有信息有一个是NO,此时就推进到阶段2RollBack。阶段2就会对所有的参与者执行rollback操作。回滚完之后就会向协调者发送ACK信息。当事务协调者收到所有参与者发送的ack信息就代表事务已经回滚了
2PC 优点缺点
优点:
原理简单
缺点:
*同步阻塞
在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,即当参与者占有公共资源时,其他节点访问公共资源会处于阻塞状态
*单点问题
若协调器出现问题,那么整个二阶段提交流程将无法运转,若协调者是在阶段二中出现问题
时,那么其他参与者将会一直处于锁定事务资源的状态中,而无法继续完成事务操作
*数据不一致
在阶段二中,执行事务提交的时候,当协调者向所有的参与者发送Commit请求之后,发生了局部网络异常或者是协调者在尚未发送完Commit请求之前自身发生了崩溃,导致最终只有部分参与者收到了Commit请求,于是会出现数据不一致的现象。以上就介绍完了2pc。
2.三阶段提交协议(3PC):
三阶段提交协议出现背景:一致性协议中设计出了二阶段提交协议(2PC),但2PC设计中还存在缺陷,于是就有了三阶段提交协议,这便是3PC的诞生背景。3PC,全称 “three phase commit”,是 2PC 的改进版,将 2PC 的 “提交事务请求” 过程一分为二,共
形成了由CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议。
阶段一:CanCommit
(1)事务询问:协调者向参与者发送一个包含事务内容的 canCommit 请求,询问是否可以执行事务提交操作,并等待响应。
(2)各参与者向协调者反馈事务询问的响应,如果参与者认为自己可以顺利执行事务,就返回 Yes,否则反馈 No 响应。
阶段 二:PreCommit
协调者在得到所有参与者的响应之后,会根据结果执行2种操作:执行事务预提交,或者中断事务。
(1)执行事务预提交:
首先协调者向所有参与者节点发出 preCommit 的请求,并等待响应。然后参与者受到 preCommit 请求后,会执行事务操作,并将结果返回。最后协调者得到了Ack响应,确定下一阶段是否为提交或者是终止操作。
(2)中断事务也分为2个步骤:
首先协调者向所有参与者节点发出 abort 请求 。然后参与者如果收到 abort 请求或者超时了,都会中断事务。
阶段三:do Commit
(1)执行提交
首先协调者发送提交请求,并等待Ack 响应。然后参与者收到 doCommit 请求后,执行事务并反馈事务提交结果,向协调者发送 Ack 消息。最后协调者接收 Ack 消息后,完成事务。
(2)中断事务
中断事务是因为出现了异常,比如协调者一方出现了问题,或者是协调者与参与者之间出现了故障。 首先协调者向所有的参与者发送中断请求。然后参与者接收到中断请求后,会利用其在二阶段记录的 undo 信息来执行事务回滚操作,并释放资源。接下来参与者在完成事务回滚之后,向协调者发送 Ack 消息。最后协调者接收到所有的 Ack 消息后,中断事务。
3pc协议的优点
3PC对于协调者和参与者都设置了超时机制,而2PC只有协调者才拥有超时机制。这个优化点,避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题。而且3pc多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。
3PC并没有完全解决一致性问题,如果协调者因网络异常或宕机,参与者集群无法接收到协调者发出的请求,有可能是一部分参与者接收到了一部分没有接收到。我们发送的是DO-commit请求,参与者有一部分接收到了就执行提交,一部分没接收到的话就在超时之后自己执行提交。这种是没问题的。有一种情况协调者向参与者发送回滚的请求,但是参与者只有一部分接收到了请求并进行回滚,但是另一部分参与者没有接收到absort回滚请求,这时候参与者就自己提交本地的事务来释放资源,这时候就会出现参与者事务不一致的情况。