分布式事务

发布时间 2023-09-27 21:50:46作者: 牧丶归

分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:

  • 跨数据源的分布式事务

  • 跨服务的分布式事务

当我们把多个事件看做一个"业务"时,要么满足保证“业务”的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象,这就是分布式系统下的事务了。总体来说,就是出现了多个数据库连接

此时ACID难以满足,这是分布式事务要解决的问题

ACID指的就是事务的四个特性,

A:指就是原子性,事务中的所有操作,要么全部成功,要么全部失。

C:指的就是一致性,事务开始前到事务结束后,数据状态需要一致。分布式事务对于一致性他要求的是最终一致性,而传统事务要求的是强一致性

I:指的就是隔离性,多个事务之间的操作相互隔离,互不影响,就比如,我这边转账,不影响你那边支付。反之亦然,隔离有四个级别:

  • 读未提交:会产生脏读、幻读、不可重复读的问题

  • 读已提交:会产生幻读、不可重复读的问题(oracle默认)

  • 可重复读:会产生幻读的问题(mysql默认)

  • 串行化:没有任何问题,但是相当于锁表,效率极低。所以这种方案不用

不同的隔离级别会产生不同的问题: 脏读:一个事务读到了另一个事务没有提交的数据 不可重复读:同一个事务中,连续读取两次,得到结果不一样 幻读:事务操作看到前和看到后的结果不一致,就像出现了幻觉一样 就比如在A事务中执行查询,看到两条数据,然后在B事务中执行增加操作,成功插入一条数据后,再在A事务中执行修改操作,发现修改影响行数为3行 D: 指的就是持久性,事务一旦提交,则永久的保存到磁盘,不可逆

分布式理论

CAP定理

分布式系统有三个指标。

  • Consistency(一致性)

  • Availability(可用性)

  • Partition tolerance (分区容错性)

它们的第一个字母分别是 C、A、P。这三个指标不可能同时做到。这个结论就叫做 CAP 定理

Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致。

比如现在包含两个节点,其中的初始数据是一致的,当我们修改其中一个节点的数据时,两者的数据产生了差异,要想保住一致性,就必须实现节点一 到 节点二的数据 同步:

Availability (可用性):用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝。就比如说有一个多个节点的集群,访问任何一个节点都可以及时得到响应,当有部分节点因为网络故障或其它原因无法访问时,代表节点不可用

Partition(分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。Tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务

CP:在一定时间内,等待集群节点进行数据同步后,对外提供访问

AP:在任何时间内,都对外访问,但是得到的数据可能不一样

CA:不能同时出现。多个节点要想数据一致,需要时间同步。那么在这个时间内,一定不能对外访问,所以A不成立。如果可以对外访问,那么数据就不一致,所以C就不成立了,如果一定要满足CA,那就没有P,也就不是分布式环境了,是单节点

在分布式系统中,系统间的网络不能100%保证健康,一定会有故障的时候,而服务又必须对外保证服务。因此分区容错不可避免。也就是说,在P一定会出现的情况下,A和C之间只能实现一个。

BASE理论

BASE理论对CAP的一种补充,放弃强一致性,追求最终一致性。 BASE理论有三个思想:

  • Basically Available(基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。譬如电商大促,为了应对大流量,暂时停止注册服务,这时注册服务就不可用,但是整个系统是可用的,所以叫基本可用

  • Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。 比如订单状态:待付款、已付款待发货、已发货、已签收、已结束

  • Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。

分布式事务的解决思路 分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论,有两种解决思路:

  • AP模式:最终一致性 各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。 譬如:增加了一条数据,后面有操作失败了,那么,补偿措施只需要把增加的那条数据删除即可,因为子事务提交了,那么提交后的状态是一个中间状态,也就是软状态

  • CP模式:强一致性 各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。事务执行过程中,会锁定操作的资源,那么这个资源暂时是不可用的。所以整个系统是基本可用

但不管是哪一种模式,都需要在子系统事务之间互相通讯,协调事务状态,也就是需要一个事务协调者(TC),这里的子系统事务,称为分支事务;有关联的各个分支事务在一起称为全局事务

Seata

Seata事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

Seata基于上述架构提供了四种不同的分布式事务解决方案:

  • XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入

  • TCC模式:最终一致的分阶段事务模式,有业务侵入

  • AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式

  • SAGA模式:长事务模式,有业务侵入

无论哪种方案,都离不开TC,也就是事务的协调者。

XA模式

XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA 规范 描述了全局的TM与局部的RM之间的接口,几乎所有主流的数据库都对 XA 规范 提供了支持

XA是规范,目前主流数据库都实现了这种规范,实现的原理都是基于两阶段提交。

一阶段:

  • 事务协调者通知每个事物参与者执行本地事务

  • 本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有数据库锁

二阶段:

  • 事务协调者基于一阶段的报告来判断下一步操作

    • 如果一阶段都成功,则通知所有事务参与者,提交事务

    • 如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务

优点 事务的强一致性,满足ACID原则。 常用数据库都支持,实现简单,并且没有代码侵入

缺点 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差 依赖关系型数据库实现事务

AT模式

AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷。

seata的AT模式

阶段一RM的工作

  • 注册分支事务

  • 记录undo-log(数据快照)

  • 执行业务sql并提交

  • 报告事务状态

阶段二RM的工作

  • 一阶段都成功,则提交,删除undo-log

  • 一阶段有失败,则回滚,恢复undo-log日志,删除undo-log

AT模式的优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能比较好

  • 利用全局锁实现读写隔离

  • 没有代码侵入,框架自动完成回滚和提交

AT模式的缺点:

  • 两阶段之间属于软状态,属于最终一致

  • 框架的快照功能会影响性能,但比XA模式要好很多

AT模式与XA模式的区别:

  • XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。

  • XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。

  • XA模式强一致;AT模式最终一致

TCC模式

TCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复。需要实现三个方法:

  • Try:资源的检测和预留;

  • Confirm:完成资源操作业务;要求 Try 成功 Confirm 一定要能成功。

  • Cancel:预留资源释放,可以理解为try的反向操作。

优缺点

TCC的优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能好

  • 相比AT模型,无需生成快照,无需使用全局锁,性能最强

  • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

TCC的缺点:

  • 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦

  • 软状态,事务是最终一致

  • 需要考虑Confirm和Cancel的失败情况,做好幂等处理