六、tcc两阶段补偿事务协议
所有文章
https://www.cnblogs.com/lay2017/p/12078232.html
正文
前面的文章中,我们先了解了2pc,知道了2pc强一致性导致的资源被长时间锁住的问题。而后,我们又了解了3pc,3pc在2pc的基础上增加了超时机制,企图解决强一致性带来的问题,但是超时机制明显会造成真正的数据不一致的可能,而且3pc也没有真的解决2pc的数据一致性问题。
tcc两阶段补偿事务提交协议
本文将了解一个跟2pc很像的事务提交协议,tcc事务提交协议,全称是:try-confirm-cancel,也是一个分为两个阶段的事务提交协议,如图所示
tcc事务提交协议分为两个阶段:
1)阶段一,主业务尝试(try)调用从业务,从业务并不直接执行,而是进行一个预留操作。比如,扣减库存问题,并不直接扣减库存,而是预留一个扣减字段,表示要扣减多少库存。
2)阶段二,在从业务都返回yes的情况下,主业务将会确认(confirm)之前的预留操作,也就是会根据之前的扣减字段直接扣减库存了。那如果不是全部yes的情况下,就会调用取消(cancel)请求,取消之前的扣减字段。
tcc与2pc有什么区别
我们发现,tcc和2pc在过程上面非常的像,有哪些相同和不同呢?
相同点
tcc和2pc都是两个阶段,一阶段并不真正的执行业务,二阶段根据一阶段的结果进行确认或者取消。所以,你会觉得在外观上两者似乎非常相似。
不同点
开发者感知
tcc和2pc的本质区别就是tcc面向的是业务层面,2pc面向的是资源层面,什么意思?
我们在学习2pc的时候,我们总说一阶段是prepare事务,也就是不真正的提交事务。也就是说对资源的更新操作实际上并没有执行,记录在事务日志中准备二阶段的commit或者rollback。但是这些对于开发者来说其实是无感知的,开发者仍旧对资源进行单一的更新操作。
而tcc,它的一阶段进行try预留操作,也就是说开发者需要从业务层面来考虑这个问题,提供try-confirm-cancel这样的一个业务逻辑来为维护事务提交,开发者对此是感知得很明显的。我们也可以理解为对业务的入侵。
强一致性和最终一致性
2pc在一定程度上我们称之为强一致性,所以2pc的执行过程会独占资源,持有资源的互斥锁,这也是2pc效率比较低的原因。而tcc虽然增加了业务代码的复杂性,但是在业务层面上避免长时间占用资源,通过一种confirm或cancel的补偿机制来完成整个业务操作,也就是保持最终一致性。最终一致性并不需要长时间持有资源的锁,每一个事务其实都是相互独立的,所以tcc的效率会更高。
总结
我们看到,tcc和2pc非常的相似,都是两阶段的性质。但是,2pc从事务资源的角度利用强一致性来解决问题,显得有些效率低下。而tcc从业务角度来解决问题,把强一致性改成了最终一致性,大大提高了效率。但是tcc明显对代码造成了入侵,你原本只需要一个接口,就不得不拆分成三个接口来处理,对开发者的要求也会更高。
另外,2pc在二阶段如果出现网络故障的情况,即使利用持久化的事务日志补偿处理也会从强一致性变成最终一致性。而tcc从一开始就决定不维护强一致性,而是遵循最终一致性。这样看来,tcc虽然增加了开发的复杂度问题,但是在使用上会更加地高效,稳定,即使极端情况下确实需要人工干预,最终一致性也能够保持。