分布式事务之2PC、3PC、TCC

目录

什么是2PC

关系型数据库的2PC=>XA方案

分布式事务框架Seata的2PC=》AT方案

Seata的2PC和传统2PC比较

2PC的问题

什么是3PC

什么是TCC


 

什么是2PC

 

2PC即两阶段提交协议,将整个事务流程分为两个阶段:准备阶段、提交阶段。

简单来说准备阶段就执行事务代码,但不一定提交,提交阶段决定是最终提交事务还是回滚事务。

为什么要简单来说?因为基于数据库的2PC和分布式框架Seata的2PC有差异,不能一概而论。

 

 

关系型数据库的2PC=>XA方案

 

数据库的2PC也叫传统2PC,是2PC在数据库层面的实现,也叫做XA方案。

XA方案由三部分组成:应用程序、事务管理器和参与者。 具体的事务执行过程如下

准备阶段(Prepare phase):

事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地Undo/Redo日志,此时事务没有提交

提交阶段(Commit phase):

如果事务管理器收到了参与者的执行失败或超时消息时,直接给每个参与者发送回滚消息;否则发送提交消息。消息发送完毕后释放使用的锁资源。

 

成功情况

分布式事务之2PC、3PC、TCC

失败情况

分布式事务之2PC、3PC、TCC

XA方案的性能不是很理想:原因在于资源锁需要等到两个阶段都结束才释放。其他进程会阻塞,性能差

 

 

分布式事务框架Seata的2PC=》AT方案

 

关于Seata的AT方案可参考下面的博客

https://blog.csdn.net/Delicious_Life/article/details/106984423 

AT模式的目标是对业务的无入侵的。这点在后端开发中非常的爽滑。可参考下面的博客感受分布式锁的实现

https://blog.csdn.net/Delicious_Life/article/details/106985083

 

 

Seata的2PC和传统2PC比较

 

1.传统2PC的RM实际上是数据库本身,而Seata的RM是以Jar包的形式作为中间件部署在应用程序一侧

2.传统的2PC第二阶段才提交、Seata的2PC在第一阶段就会将本地事务提交,这样减少了Phase2的持锁实际,提高整体效率 

 

 

2PC的问题

 

2PC的事务协调者一定要高可用,即把Seata设置成集群(否则会出现单点故障问题)。

此外,当经历了阶段一协调者告诉参与者可以提交时,参与者1和2正确提交,参与者3因为网络原因没有收到消息则无法提交。此时会出现数据不一致的情况

 

 

什么是3PC

 

三阶段提交又称3PC,其在两阶段提交的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了2PC的协调者单点故障的问题。但是性能问题和不一致问题仍然没有根本解决。

3PC的第一个阶段可理解为预备、即事务协调者会先循环参与者是否可以完成各自的请求,参与者需向协调者回复是或否

第二阶段仍可理解为2pc的准备,事务协调者让参与者执行各自的请求,参与者执行完毕回复协调者

第三阶段提交:提交事务或者回滚事务。

相比较2PC而言,3PC对于协调者(Coordinator)和参与者(Partcipant)都设置了超时时间,而2PC只有协调者才拥有超时机制。这解决了一个什么问题呢?这个优化点主要是避免了参与者在长时间无法与协调者节点通讯(协调者挂掉了)的情况下,无法释放资源的问题,因为参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面降低了整个事务的阻塞时间和范围。

3PC当然也可能出现数据不一致的现象,但出问题的概率又被大大缩减了~

 

 

什么是TCC

 

TCC是分布式事务的又一种解决方案。TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。 

 

分支事务执行成功

分布式事务之2PC、3PC、TCC

分支事务执行失败 

分布式事务之2PC、3PC、TCC

 

TCC最大的问题就是对应用程序的侵入性非常强

如果拿TCC事务的处理流程与2PC两阶段提交做比较,2PC通常都是在跨库的DB层面,而TCC则在应用层面的处理,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据操作的粒度,使得降低锁冲突、提高吞吐量成为可能。而不足之处则在于对应用的侵入性非常强,业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此
外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。