分布式事务就是在一个交易中各个服务之间的相互调用必须要同时成功或者同时失败,保持一致性和可靠性。在单体项目架构中,在多数据源的情况下也会发生 分布式事务问题。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
在传统的单机环境中,事务处理通常符合ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。在这种情况下,一个事务要么完全执行成功,将所有的更改提交到数据库中,要么完全失败,将所有的更改回滚,数据库状态不受影响。
Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致。
Availability(可用性):用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝。
Partition tolerance(分区容错性)
Partition(分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。
Tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务。
在分布式系统中,系统间的网络不能100%保证健康,一定会有故障的时候,而服务有必须对外保证服务。因此P不可避免。当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足。
Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。 Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
解决分布式事务的思想和模型:
分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论,有两种解决思路:
AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。
CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。
全局事务:整个分布式事务
分支事务:分布式事务中包含的每个子系统的事务
最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据 强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚
Seata事务管理中有三个重要的角色:
TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状。
Seata提供了四种不同的分布式事务解决方案:
XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入。
TCC模式:最终一致的分阶段事务模式,有业务侵入 AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式。
SAGA模式:长事务模式,有业务侵入。
XA是规范,目前主流数据库都实现了这种规范,实现的原理都是基于两阶段提交。
RM一阶段的工作:
a. 注册分支事务到TC b.执行分支业务sql但不提交 c.报告执行状态到TC
TC 二阶段的工作:
TC检测各分支事务执行状态:
a.如果都成功,通知所有RM提交事务
b.如果有失败,通知所有RM回滚事务 RM
二阶段的工作: 接收TC指令,提交或回滚事务。
XA模式的优点是什么?
事务的强一致性,满足ACID原则。
常用数据库都支持,实现简单,并且没有代码侵入
XA模式的缺点是什么?
因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差。
依赖关系型数据库实现事务。
AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷。
阶段一RM的工作:
a. 注册分支事务 b.记录undo-log(数据快照) c.执行业务sql并提交 d.报告事务状态
阶段二提交时RM的工作:
删除undo-log即可。
阶段二回滚时RM的工作:
根据undo-log恢复数据到更新前
AT模式与XA模式最大的区别是什么?
1、XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
2、XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
3、XA模式强一致;AT模式最终一致。
AT模式的优点:
一阶段完成直接提交事务,释放数据库资源,性能比较好。
利用全局锁实现读写隔离。
没有代码侵入,框架自动完成回滚和提交。
AT模式的缺点:
两阶段之间属于软状态,属于最终一致。
框架的快照功能会影响性能,但比XA模式要好很多。
TCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复。需要实现三个方法:
Try:资源的检测和预留。
Confirm:完成资源操作业务;要求 Try 成功 Confirm 一定要能成功。
Cancel:预留资源释放,可以理解为try的反向操作。
TCC模式的每个阶段是做什么的?
Try:资源检查和预留
Confirm:业务执行和提交
Cancel:预留资源的释放
TCC的优点是什么?
一阶段完成直接提交事务,释放数据库资源,性能好。
相比AT模型,无需生成快照,无需使用全局锁,性能最强。
不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库。
TCC的缺点是什么?
有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦。
软状态,事务是最终一致。
需要考虑Confirm和Cancel的失败情况,做好幂等处理。
在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。
分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会去退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。
Saga也分为两个阶段:
一阶段:直接提交本地事务。
二阶段:成功则什么都不做;失败则通过编写补偿业务来回滚。
优点:
事务参与者可以基于事件驱动实现异步调用,吞吐高。
一阶段直接提交事务,无锁,性能好。
不用编写TCC中的三个阶段,实现简单。
缺点:
软状态持续时间不确定,时效性差。
没有锁,没有事务隔离,会有脏写。