背景
随着企业的高速发展,原本的单机应用日渐无法满足业务需求,所以需要从横行、纵向等维度,对企业应用进行拆分,这其中包括业务的拆分、服务器的拆分、应用的拆分、数据库的拆分。此时拆分后由多个子系统组成的系统,叫做分布式系统。
什么是分布式事务?
分布式事务就是指事务的资源分别位于不同的分布式系统的不同节点之上的事务;简单理解就是,在单个数据库操作下,我们可以利用数据库的ACID特性去完成一个事务,但是在业务涉及到多个数据库操作下,每个数据库的ACID特性只会在自己的范围内产生作用,数据库之间无法保证ACID,所以就产生了分布式事务。
例:老王的老婆要炒菜,叫老王去买锅,叫儿子去买菜,单库事务情况下,如果锅买不到或者菜买不到,那么另外一个也不买,菜也不炒了,事务失败;多库事务情况下,买不到锅或者买不到菜,对方又不知道,回到家,完了,菜炒不成,钱也退不了,此时事务失败,但是无法回滚。
刚性事务?柔性事务?
单数据库事务完全遵循ACID规范,属于刚性事务。分布式事务要完全遵循ACID非常困难,分布式事务属于柔性事务,满足BASE理论:BA(Basic Availability 基本业务可用性)、S(Soft state 柔性状态)、E(Eventual consistency 最终一致性);
柔性事务对于ACID的支持
A.原子性:严格遵守;
C.一致性:事务完成后的一致性严格遵循,事务中的一致性可适当放宽;
I.隔离性:并行事务间不可影响;事务中间结果可见性允许安全放宽;
D.持久性:严格遵循;
为了可用性、性能的需要,柔性事务降低了一致性(C)与隔离性(I) 的要求,即“基本可用,最终一致”;
柔性事务分类
柔性事务分为:两阶段提交型、补偿型、异步确保型、最大努力通知型。
1.两阶段提交型
对应技术上的XA、JTA/JTS,这是分布式环境下事务处理的典型模式。
2.补偿型
TCC型事务(Try、Confirm、Cancel)是其中一种补偿型事务,思路是:尽早释放锁;在Try成功的情况下,Confirm肯定成功;如果事务要回滚,Cancel作为补偿操作,回滚Try操作;
TCC型事务是将事务本地化,将资源层的两阶段提交协议拆分转换到业务层,所以对业务代码有入侵。
Seata框架中的分布式事务,也是属于一种补偿型事务,思路是:将2PC中事务协调器从应用框架中独立出来,解决单点问题;同时接管数据源,对事务内的所有写操作的sql语句进行捕捉并生成逆向sql并保存,当事务失败的时候,事务协调器只要执行事务产生的逆向sql,就能达到事务回滚的效果。
Seata的分布式事务,是从XA事务演化来的,优点是对代码无入侵,但需要接管数据源,基本上等于改造了一遍资源层。
3.异步确保型
将一些同步阻塞的事务操作变为异步的操作,避免对数据库事务的争用;比如消息事务机制。
例如:RocketMQ。
4.最大努力通知型
通过通知服务器(消息通知)进行,允许失败,有补充机制;
例如:银行通知、商户通知等。