二者都是分布式事务的解决方案
2pc:
整个事务分成两个阶段:
阶段一:表决阶段,所有参与者都预提交(只执行sql,但不提交)事务,并将信息反馈发给协调者。
阶段二:执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地执行提交或回滚。
该方案的优点
- 提高了数据一致性的概率,实现成本较低
该方案的缺点
- 单点问题:事务协调者宕机,参与者会一直阻塞下去
- 同步阻塞:延迟了提交时间,加长了资源阻塞时间,影响整体性能
- 数据不一致:在第二阶段提交时,依然存在commit结果未知的情况,有可能导致数据不一致
3pc
三阶段提交协议,是二阶段提交协议的改进版本,三阶段提交相较于二阶段提交协议有两个改动点
1. 增加了CanCommit阶段
2. 引入了超时机制
第一阶段:CanCommit阶段。
所有参与者确认自己是否能正常进行事务(是否能访问到对应的资源),把结果发送给协调者,以及是否能接到协调者的消息。
第二阶段:PreCommit阶段。
所有参与者执行事务,但是不提交事务,仅仅是把事务执行成功或失败的消息发送给协调者。
第三阶段:DoCommit阶段
协调者向所有参与者发起事务提交或回滚的通知。
3PC和2PC的区别
- CanCommit阶段就是3PC相比2PC多出来的一个阶段,在2PC中的第一阶段,参与者会直接执行事务,也就会生成undo日志。而在3PC中,这个CanCommit阶段会进行“试水”操作,降低做出无效的undo日志的几率。
- 2PC中,只要事务参与者没有收到协调者的commit消息,就会一直阻塞。而在3PC中,一旦事务参与者迟迟没有收到协调者的commit消息,就会自动进行本地commit。这样相对有效地解决了协调者单点故障的问题。
- 3PC中,在DoCommit阶段,如果参与者没有及时收到来自协调者的commit或者abort消息,参与者就会在等待超时后,直接自行提交事务。这样做除了避免参与者一直占着资源不释放的问题外,还有另外一个原因:参与者能进入第三阶段,说明参与者在第二阶段已经收到了协调者的PreCommit消息,而协调者发送PreCommit消息的前提是,在第二阶段开始之前,协调者收到了所有参与者的CanCommit响应都是Yes。这说明所有的参与者都认为自己有能力正确处理处理事务。所以,当参与者进入第三阶段后,由于网络超时等原因,参与者会在等待超时后自动提交,因为参与者相信,直接提交的话,有很大几率是整个分布式事务是成功的!
注意
3PC仍然没有解决2PC的性能问题和不一致问题(如果协调者确实给所有参数与发送的都是中断事务的消息,而某个参与者没有收到,超时之后,只有它自己直接提交了,而其他参与者却是回滚了,此时就造成数据不一致的情况。不过可以用日志记录在超时之后提交事务的日志,让人工进行检查)。3PC仅仅是增大了分布式事务的成功几率。