前言
随着互联网技术的不断发展,系统越来越复杂,几乎所有 IT 公司的系统都已经完成从单体架构到分布式架构的转变,分布式系统几乎无处不在,分布式事务由此产生。
事务
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。
而事务分为本地事务和分布式事务。本地事务常用于单体架构、分布式事务用于分布式架构。
1)本地事务
本地事务也成为数据库事务和传统事务。
执行模式(简单):
1、开启事务。transaction beagin
2、数据执行变更。insert update delete
3、提交事务/数据回滚 transaction commit/transaction rollback
以MySQL为例,在这执行过程中同样需要保证ACID。而这保证基于mvcc+锁机制(redo log、undo log、回滚指针、自增ID、Read View)
2)分布式事务
**分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。**基于事务的原则,这些服务器之间的操作要么全部成功、要不全部失败。
本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
介绍
Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。Seata分为三大模块,分别是 TM、RM 和 TC。
**TC (Transaction Coordinator) - 事务协调者:**维护全局和分支事务的状态,驱动全局事务提交或回滚。
**TM (Transaction Manager) - 事务管理器:**定义全局事务的范围:开始全局事务、提交或回滚全局事务。
**RM (Resource Manager) - 资源管理器:**管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署。
服务端存储模式支持三种:
file: 单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高(默认)。
DB: 高可用模式,全局事务会话信息通过DB共享,相对性能差一些。
redis: Seata-Server1.3及以上版本支持,性能较高,存在事务信息丢失风险,需要配合实际场景使用。
特性
**1、微服务支持。**目前已支持Dubbo、Spring Cloud、Sofa-RPC、Motan 和 gRPC 等RPC框架,其他框架持续集成中
**2、高可用。**支持计算分离集群模式,水平扩展能力强的数据库和 Redis 存储模式,Raft模式Preview阶段
**3、多种事务模式。**XA、AT、TCC、SAGA模式。其中AT、TCC、SAGA,这三个都是补偿型事务。
分布式事务使用场景
1、转账
增减操作,需要用分布式事务来保证一进一出原则。
2、下单扣减库存
用来保证不会被超卖,同一时间段,最多只能拿到剩余库存数量的锁。
3、同步超时
在使用第三方支付时,通常采用异步方案,但是支付结果往往通过回调才能获知,所以会存在一定时间段的显示延迟。
如果没有分布式事务的保证,就会出现用户订单实际支付情况与最终用户看到的订单支付情况不一致的情况。
模式
AT模式
AT模式是一种没有侵入的分布式事务的解决方案,在AT模式下,用户只需关注自己的业务SQL,用户的业务SQL作为一阶段,Seata框架会自动生成事务进行二阶段提交和回滚操作。
两阶段提交协议的演变:
-
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
在一阶段中,Seata会拦截业务SQL ,首先解析SQL语义,找到要操作的业务数据,在数据被操作前,保存下来记录 undo log,然后执行 业务SQL 更新数据,更新之后再次保存数据 redo log,最后生成行锁,这些操作都在本地数据库事务内完成,这样保证了一阶段的原子性。
二阶段负责整体的回滚和提交,如果之前的一阶段中有本地事务没有通过,那么就执行全局回滚,否在执行全局提交,回滚用到的就是一阶段记录的 undo Log ,通过回滚记录生成反向更新SQL并执行,以完成分支的回滚。当然事务完成后会释放所有资源和删除所有日志。
-
二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。
流程如下:
底层流程执行过程:
如图所示:
完整流程图:
TCC模式
TCC 是分布式事务中的二阶段提交协议,它的全称为 Try-Confirm-Cancel,即资源预留(Try)、确认操作(Confirm)、取消操作(Cancel),他们的具体含义如下:
- Try:对业务资源的检查并预留。
- Confirm:对业务处理进行提交,即 commit 操作,只要 Try 成功,那么该步骤一定成功。
- Cancel:对业务处理进行取消,即回滚操作,该步骤回对 Try 预留的资源进行释放。
TCC 是一种侵入式的分布式事务解决方案,以上三个操作都需要业务系统自行实现,对业务系统有着非常大的入侵性,设计相对复杂,但优点是 TCC 完全不依赖数据库,能够实现跨数据库、跨应用资源管理,对这些不同数据访问通过侵入式的编码方式实现一个原子操作,更好地解决了在各种复杂业务场景下的分布式事务问题。
SAGA模式
Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务(执行处理时候出错了,给一个修复的机会)都由业务开发实现。
**Saga 模式下分布式事务通常是由事件驱动的,各个参与者之间是异步执行的,Saga 模式是一种长事务解决方案,提供了异构系统的事务统一处理模型。在Saga模式中,所有的子业务都不在直接参与整体事务的处理(只负责本地事务的处理),而是全部交由了最终调用端来负责实现,而在进行总业务逻辑处理时,在某一个子业务出现问题时,则自动补偿全面已经成功的其他参与者,这样一阶段的正向服务调用和二阶段的服务补偿处理全部由总业务开发实现。**使用场景:事务参与者可能是其他公司的服务或者是遗留系统,无法改造,可以使用Saga模式。
Saga状态机
目前Seata提供的Saga模式只能通过状态机引擎来实现,需要开发者手工的进行Saga业务流程绘制,并且将其转换为Json配置文件,而后在程序运行时,将依据子配置文件实现业务处理以及服务补偿处理,而要想进行Saga状态图的绘制,一般需要通过Saga状态机来实现。
Saga状态机是采用状态模式。示例:https://github.com/seata/seata/blob/develop/saga/seata-saga-statemachine-designer/README.zh-CN.md
基本原理:
- 通过状态图来定义服务调用的流程并生成json定义文件。
- 状态图中一个节点可以调用一个服务,节点可以配置它的补偿节点。
- 状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚。
- 可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能。
XA模式
最早的分布式事务处理方案,因为需要数据库内部也是支持XA模式的,比如MYSQL,XA模式具有强一致性的特点,因此他对数据库占用时间比较长,所以性能比较低。
两阶段提交。
- 第一阶段进行事务注册,将事务注册到TC中,执行SQL语句。
- 第二阶段TC判断无事务出错,通知所有事务提交,否则回滚。
- 在第一到第二阶段过程中,事务一直占有数据库锁,因此性能比较低,但是所有事务要么一起提交,要么一起回滚,所以能实现强一致性。
执行阶段:
- 可回滚:业务SQL操作在XA分支中进行,有资源管理器对XA协议的支持来保证可回滚。
- 持久化:ZA分支完成以后,执行 XA prepare,同样,由资源对XA协议的支持来保证持久化。
完成阶段:
- 分支提交:执行XA分支的commit。
- 分支回滚:执行XA分支的rollback。
什么是XA协议?
XA规范是X/OPEN组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA规范描述了全局事务管理器和局部资源管理器之间的接口,XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列等)在同一事务中访问,这样可以使 ACID 属性跨越应用程序而保持有效。
XA 规范使用两阶段提交(2PC,Two-Phase Commit)来保证所有资源同时提交或回滚任何特定的事务。因为XA规范最早被提出,所以几乎所有的主流数据库都保有对XA规范的支持。
分布式事务DTP模型定义的角色如下:
- AP:即应用程序,可以理解为使用DTP分布式事务的程序,例如订单服务、库存服务。
- RM:资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库的实例(MySql),通过资源管理器对该数据库进行控制,资源管理器控制着分支事务。
- TM:事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理实务生命周期,并协调各个RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务。
TCC和AT区别
AT 模式基于 支持本地 ACID 事务 的 关系型数据库:
- 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
- 二阶段 commit 行为:马上成功结束,自动异步批量清理回滚日志。
- 二阶段 rollback 行为:通过回滚日志,自动生成补偿操作,完成数据回滚。
相应的,TCC 模式,不依赖于底层数据资源的事务支持:
- 一阶段 prepare 行为:调用自定义的 prepare 逻辑。
- 二阶段 commit 行为:调用自定义的 commit 逻辑。
- 二阶段 rollback 行为:调用自定义的 rollback 逻辑。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。
原理分析
使用说明
其他
1、强一致性、弱一致性、最终一致性
强一致性
任何一次读都能读到某个数据的最近一次写的数据。系统中的所有进程,看到的操作顺序,都和全局时钟下的顺序一致。简言之,在任意时刻,所有节点中的数据是一样的。
弱一致性
数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。
最终一致性
不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。简单说,就是在一段时间后,节点间的数据会最终达到一致状态。
2、CAP原则
CAP 原则又称 CAP 定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
一致性 C
在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性 A
在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容错性 P
分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择。 CAP 原则的精髓就是要么 AP,要么 CP,要么 AC,但是不存在 CAP。
如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时 C 和 P 两要素具备,
但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了 CP 系统,但是 CAP 不可同时满足。
BASE理论
BASE 理论指的是基本可用 Basically Available,软状态 Soft State,最终一致性 Eventual Consistency,核心思想是即便无法做到强一致性,但应该采用适合的方式保证最终一致性。
BA:Basically Available 基本可用,分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
S:Soft State 软状态,允许系统存在中间状态,而该中间状态不会影响系统整体可用性。
E:Consistency 最终一致性,系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
BASE 理论本质上是对 CAP 理论的延伸,是对 CAP 中 AP 方案的一个补充。
总结
总得来说,Seata的中AT模式基本可以满足百分之80的分布式事务的业务需求,AT模式实现的是最终一致性,所以可能存在中间状态。而XA模式实现的强一致性,所以效率较低一点,。Saga可以用来处理不同开发语言之间的分布式事务,所以关于分布式事务的四大模型,基本可以满足所有的业务场景。这些模式中XA和AT没有业务侵入性,而Saga和TCC具有一定的业务侵入。