分布式事务分析

近期公司项目基于微服务架构需要涉及到实现一套分布式事务。经过几天在网上查阅资料发现大部分文章只是讲解了具体的其中一个模型。因此在这里做一个总结+自己的一些感悟和看法。

1.CAP理论

CAP理论本身并不是一套和事务相关的理论,而是用来解释分布式系统的理论。但是用来分析分布式事物的边界非常适合。关于CAP理论,可以查看阮一峰大神的这篇文章:CAP定理的含义

CAP理论一个核心论证就是P(分区容错性)作为一个分布式系统是肯定包含的。因此实际实现只是在CP和AP之间做抉择。

CP:为了保证一致性和分区容错性,那么肯定会丧失一部分可用性。

AP:为了保证可用性和分区容错性,那么肯定会丧失一部分一致性。

2.ACID原则

ACID原则是用来描述一个事务应该包含的特性。原子性、一致性、隔离性、持久性。这个原则实际上和CAP理论是相悖的。

3.刚性事务、CP模式、XA协议

我们来假设一个简单的支付场景,生成订单--->扣用户积分--->核销优惠劵--->修改订单状态。这里涉及三个系统,订单系统、用户积分系统、优惠劵系统。那么如果我们要保证事务的一致性,我们在其中的每一步都会将资源锁定,然后只有在最终事务全部完成后,我们才能释放锁。那么在整个事务周期内我们的功能必定是处于不可用状态。这也正符合CP定义。这么做的事务确实可以保证事务的ACID原则,但是因为锁定时间长、锁粒度大(锁定资源多),在高并发的情况下,并不适用。这一类强一致性事务,称为刚性事务

Mysql在5.6之前就支持了XA协议,允许使用刚性事务。当然Mysql仅仅是支持了协议,提供了接口。XA协议中的2PC(2阶段提交)模型中的全局管理者和参与者还是需要自己实现。

4.柔性事务、AP模式、TCC模型、消息事务模型

刚性事务既然不符合常用的场景,那么我们就只能牺牲一部分一致性,保证最终一致性。也就是BASE理论基本可用、软状态、最终一致性。这一类事务称为柔性事务,常见的模型有两类,TCC模型:try-confirm-cancel。基于消息系统的实现:最大努力通知型、可靠消息型。

5.真的需要分布式事务吗?

在真正的开始使用、实现分布式事务前,我们先要确定自己的需求真的需要一个分布式事务才可以实现吗?依然是之前的场景:生成订单--->扣用户积分--->核销优惠劵--->修改订单状态

整个流程都是同步调用,那么作为下一个步骤的发起方总是能获取被动方执行的结果。如果其中任何一个被动方报错,那么只需要上一步一步的回滚就可以了。

当然其中的每一步都是一个局部本地的事务,执行下一步操作之前,当前的本地事务肯定是已经完成了,那么回滚当然不能简单的rollback()就可以了。其实可以每一个步骤实现一个回退的接口。当出现需要回滚的情况时候,由最上层的发起方依次调用指定服务的回退接口就可以了。

这种实现实际上完全BASE理论,从出现问题到全部回滚完之前的中间状态下,数据确实是不一致的,但是回滚之后就是符合最终一致性的。根据前文所说的CAP理论,在分布式系统下你是不可能保证数据的强一致性的!!!。因此,如果你使用分布式事务是简单的任务能满足强一致性,推荐你使用刚性事务实现。

6.同步场景下柔性事务还有意义吗?

通过之前的分析,其实同步场景下只需要通过上层调用实现的回滚接口就可以避免使用分布式事务,那么这种柔性事务还有什么意义呢?所谓的TCC模型、消息模型还有什么意义呢?我的理解是虽然同步调用情况下可以通过前文所说避免柔性事务,但是还是可能有完全不一致的情况出现。

首先就是上层调用方直接挂掉了。整个调用链断掉了。这种情况下当然可以通过监控、校对来进行干预。

第二种情况我认为就是对代码结构的封装了,如果每一个类似的调用链都需要开发者自己去手动判断+调用回滚,容易遗漏、出错,并且破坏代码结构。这种情况下使用一个统一的分布式事务将事务间的关联管理起来,回滚等操作都调用方来说都不透明似乎是一个很好的选择。

因此根据你的实际需求,分析是否真的需要使用柔性事务,是否可以直接通过调用链的方式避免使用分布式事务系统。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章