1 二阶段提交协议(2PC:Two-Phase Commit)
二阶段提交,是指将事务提交分成两个部分:准备阶段和提交阶段。事务的发起者称之为协调者,事务的执行者称为参与者。
1.1 阶段一:准备阶段
由协调者发起并传递带有事务信息的请求给各个参与者,询问是否可以提交事务,并等待返回结果。各个参与者执行事务操作,将Undo和Redo放入事务日志中(但是不提交)
如果参与者执行成功就返回YES(可以提交事务),失败NO(不能提交事务)
1.2 阶段二:提交阶段
- 提交事务:(所有参与者均反馈YES)
- 协调者向所有参与者发出正式提交事务的请求(即Commit请求)。
- 参与者执行Commit请求,并释放整个事务期间占用的资源。
- 各参与者向协调者反馈Ack完成的消息。
- 协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
- 中断事务:(任何一个参与者反馈NO)
- 协调者向所有参与者发出回滚请求(即Rollback请求)。
- 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
- 各参与者向协调者反馈Ack完成的消息。
- 协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
1.3 2PC的优势
- 长时间阻塞状态发生的几率非常低,效率高,实际更常见
1.4 2PC的缺陷
- 阻塞:最大的问题即同步阻塞,即:所有参与事务的逻辑均处于阻塞状态。
- 单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。
- 脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。
由于2PC存在如上同步阻塞、单点、脑裂问题,因此又出现了2PC的改进方案,即3PC。
2 三阶段提交协议(3PC:Three-Phase Commit )
3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、do Commit三个阶段来进行处理。
2.1 阶段一:CanCommit
- 协调者向所有参与者发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。
- 参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态,否则反馈NO。
2.2 阶段二:PreCommit
- 事务预提交:(所有参与者均反馈YES时)
- 协调者向所有参与者发出PreCommit请求,进入准备阶段。
- 参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。
- 各参与者向协调者反馈Ack响应或No响应,并等待最终指令。
- 中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
- 协调者向所有参与者发出abort请求。
- 无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。
2.3 阶段三:DoCommit
- 提交事务:(所有参与者均反馈Ack响应时)
- 如果协调者处于工作状态,向所有参与者发出abort请求。
- 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
- 各参与者向协调者反馈Ack完成的消息。
- 协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
- 中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
- 如果协调者处于工作状态,向所有参与者发出abort请求。
- 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
- 各参与者向协调者反馈Ack完成的消息。
- 协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
注意:进入阶段三后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的 do Commit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。
2.4 3PC的优点和缺陷
- 优点:降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。
- 缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
2.5 与2PC对比
- 阻塞动作延后到这个「准备提交」环节再做,使得阻塞范围缩小为2PC的2/3。
- 新引入了timeout机制,在发生超时执行默认约定,避免了永久阻塞,也因此对多个参与者下的100%数据一致性作出了妥协。
- 同时还解决了协调者的单点问题。故障恢复或者新接替的协调者,可以利用「准备提交」产生的状态结果,来作为参与者和协调者在「提交」出现故障恢复后的界定依据。
- 两阶段提交协议中所存在的长时间阻塞状态发生的几率还是非常低,所以虽然三阶段提交协议相对于两阶段提交协议对于数据强一致性更有保障,但是因为效率问题,两阶段提交协议在实际系统中反而更加常见。
3 TCC(柔性事务,最终一致)
在国内,由于阿里的光环加持下TCC好像更火,风头盖过了2PC和3PC。其本质上是另辟蹊径达到了和3PC类似的效果。
3.1 相对于2PC或者3PC的优化
- 通过运用本地事务代替了全局事务,使得可以不需要协调者的存在,避免了协调者的单点问题。
- 3PC中协调者的另一个作用:故障恢复后的数据一致性。在TTC里通过事务日志来确保。
简单来说TCC也有点像2PC,只是TCC位于业务服务层而非资源层 TCC没有单独的准备(Prepare)阶段,Try操作兼备资源操作与准备能力 • Try操作可以灵活选择业务资源的锁定粒度(以业务定粒度) TCC有较高开发成本,因为你还要开发很多补偿性的接口。比如原来你只有一个金额加的接口,你现在可能需要开发一个金额减的接口以备补偿的时候使用。但现在企业最不缺的就是程序员,故大多企业使用这种方式实现。TCC 分布式事务框架 ByteTCC、Himly、TCC-transaction。简单来说这些框架可以很方便的帮你实现TCC。比如你可以在方法上加个注解来说明方法失败后调用此方法方法进行回滚。用通俗易懂的方式讲解了TCC和基于可靠消息服务的分布式事务。
3.2 TCC事务几种实现方案
- 最大努力通知(定期校对)(最终一致):如果你做过支付系统的话,就会知道我们接支付宝,微信支付的时候有个场景是需要定期去查询 支付宝,微信主动查询支付状态的,这就是定期校对。
- 基于于可靠消息服务的分布式事务(最终一致):大体来说就是比如订单系统在订单提交后需要把发货这个消息发送给物流系统,而只要订单系统保证这个消息能100%发送到MQ,物流系统能100%消费掉这个消息,就能实现分布式事务的最终一致性。与TCC类似,只是这个更适合异步的场景。
3.3 TCC的实现框架
- Himly
- TCC-transaction
参考
https://blog.csdn.net/xj15010735572/article/details/86233456
https://blog.csdn.net/qq32933432/article/details/87277686