两阶段提交协议(Two Phase Commit)是分布式事务中的一种常见协议,算法思路可以概括为参与者将操作成败通知给协调者,再由协调者根据所有参与者的反馈情况决定各参与者要提交操作还是中止操作。
可以分为两个阶段:准备阶段和提交阶段
)
- 准备阶段:协调者让参与者执行事务,但是并不提交,协调者返回执行情况。这个阶段参与者会记录
Redo,Undo
信息,用于后续提交和回滚 - 提交阶段:协调者根据准备阶段的情况,要求参与者提交或者回滚,参与者返回提交或回滚的结果。准备阶段任何一个节点执行失败了,就都会回滚。全部执行就提交。
两阶段提交协议缺点很多。最大缺点是在执行过程中节点都处于阻塞状态,也就是节点之间在等待对方的响应消息时,什么也做不了。特别是如果某个节点在已经占有了某项资源的情况下,为了等待其他节点的响应消息而陷入阻塞状态时,当第三个节点尝试访问该节点占用的资源时,这个节点也会连带着陷入阻塞状态。
此外,协调者也是关键,如果协调者崩溃,整个分布式事务都无法执行。所以,如果协调者是单节点,那么就容易出现单节点故障。而且协调者采用保守策略。如果一个节点在第一阶段没有响应,那么协调者会执行回滚。所以可能会引起不必要的回滚。
这里还有一个问题,很少有人会想到。如果第二阶段,协调者发送Commit的时候,参与者没有收到会怎么样?
那么协调者会不断重试,直到请求发送成功。
但是如果参与者已经收到了Commit请求,但是在提交前就宕机了又该怎么样?
参与者在恢复过来之后会查看自己本地的日志,看有没有收到Commit的指令,如果已经收到了,就会使用Redo信息来提交事务。
总的来说,两阶段提交协议是分布式事务中最常用的协议之一,它可以有效地保证分布式事务地一致性和可靠性。