2PC(强一致性解决方案)
实现
1。准备阶段:协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估指令可以完成,参与者会写 redo 和 undo 日志,然后锁定资源,执行操作,但是并不提交。
2.实现阶段:如果每个参与者明确返回准备成功,也就是预留资源和执行操作成功,协调者向参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源;如果任何一个参与者明确返回准备失败,也就是预留资源或者执行操作失败,协调者向参与者发起中止指令,参与者取消已经变更的事务,执行 undo 日志,释放锁定的资源。
此种方式的缺点:
1.阻塞:从上面的描述来看,对于任何一次指令必须收到明确的响应,才会继续做下一步,否则处于阻塞状态,占用的资源被一直锁定,不会被释放。
2.单点故障:如果协调者宕机,参与者没有了协调者指挥,会一直阻塞,尽管可以通过选举新的协调者替代原有协调者,但是如果之前协调者在发送一个提交指令后宕机,而提交指令仅仅被一个参与者接受,并且参与者接收后也宕机,新上任的协调者无法处理这种情况。
3.脑裂:协调者发送提交指令,有的参与者接收到执行了事务,有的参与者没有接收到事务,就没有执行事务,多个参与者之间是不一致的。
升级的3PC在2PC基础上多了个一个预提交操作:3PC就是把2PC的Commit阶段拆成了PreCommit和Commit两个阶段.
增加了等待超时的处理逻辑,如果在询问阶段等待超时,则自动中止;如果在准备阶段之后等待超时,则自动提交。这也是根据概率统计上的正确性最大。
加这个操作可以实现的效果:
在预提交之前协调者掉线的话,其他参与者可以得出结论不是每个参与者都收到预提交的结果, 从而放弃或选出新的协调者; 在这个预提交之后协调者掉线的话, 每个预提交着会放心的commit, 因为他们知道其他提交者也都做同样的计划.
三阶段提交协议相比二阶段提交协议,避免了资源被无限锁定的情况。但也增加了系统的复杂度,增加了参与者和协调者之间的通信次数。
2PC使用两个roundtrip来达成新的共识或维持旧有的共识. 其局限性在于不能保证有节点永久性崩溃(fail-stop)的情况下算法能向前推进;
3PC扩展了2PC, 使用三个roundtrip达成共识. 其局限性在于不能保证在节点暂时性崩溃(fail-recover), 或是有网络划分的情况下, 共识依旧成立.
最终一致性解决方案
实现:见个人Mq和db如何保证数据一致性
https://www.jianshu.com/p/cead4e4eb827
TCC方案
实现
业务层面的2pc一致性解决方案,由服务 A、服务B、服务C、服务D 共同组成的一个微服务架构系统。服务A 需要依次调用服务B、服务C 和服务D 共同完成一个操作。当服务A 调用服务D 失败时,若要保证整个系统数据的一致性,就要对服务B 和服务C 的invoke 操作进行回滚,执行反向的revert 操作。回滚成功后,整个微服务系统是数据一致的。
关键点:
服务调用链必须被记录下来。
每个服务提供者都需要提供一组业务逻辑相反的操作,互为补偿,同时回滚操作要保证幂等。
必须按失败原因执行不同的回滚策略。