详解阿里开源分布式事务框架Seata

博文小编

2021-11-25

Seata发展历史

笔者于2014年开始着手解决阿里巴巴集团内部业务的分布式事务问题,从0到1研发一个支持非侵入模式(内部称之为AT模式,即自动模式)和TCC模式(内部称之为MT模式,即手动模式)的分布式事务中间件TXC(Taobao Transaction Constructor)。TXC被广泛应用于阿里巴巴集团内部业务,主要用于解决HSF服务框架下多个数据库读写间的一致性问题。在实际业务使用中,以非侵入模式为主,TCC模式为辅助。

2016年开始,这个产品以云服务的形式对外输出,名称为GTS(Global Transaction Service),服务于众多大型私有云用户和公有云用户。

2019年1月,阿里巴巴中间件团队推出了GTS开源版本 Fescar(Fast & Easy Commit And Rollback),并和开源社区一起共建开源分布式事务解决方案。Fescar的愿景是:让分布式事务的使用像本地事务的使用一样简单和高效,并逐步解决开发者们遇到的分布式事务方面的所有难题。

在Fescar开源后,蚂蚁金服加入Fescar社区参与共建,随后Fescar被改名为Seata(Simple Extensible Autonomous Transaction Architecture)。虽然Seata目前已经包含了多种事务模式,但其最吸引客户的始终是AT模式,因为技术发展趋势一定是从侵入式到非侵入式,提高研发效率。

Seata总体架构

Seata代码总量不大,目录结构比较简洁。

模块组成

Seata的目录结构如下图所示。

各模块的说明如下。

逻辑结构

Seata有3个主要角色:TM(Transaction Manager)、RM(Resource Manager)和TC(Transaction Coordinator)。

其中,TM和RM是以SDK的形式作为Seata的客户端与业务系统集成在一起,TC作为Seata的服务端独立部署,如下图所示。

Seata处理分布式事务的主要流程如下图所示。

Seata 事务模式

Seata支持4种事务模式:AT、TCC、Saga、XA。本节做一个简要说明,后面章节会对AT模式和TCC模式进行深入剖析。

AT模式

AT 模式是 Seata 主推的分布式事务解决方案,对业务无侵入,真正做到了业务与事务分离,用户只需关注自己的“业务 SQL语句”。

AT模式使用起来非常简单,与完全没有使用分布式事务方案相比,业务逻辑不需要修改,只需要增加一个事务注解@GlobalTransactional即可,如下图所示。

TCC模式

TCC 模式需要用户根据自己的业务场景实现 try()、confirm() 和 cancel()这3个方法:事务发起方在一阶段执行try()方法,在二阶段提交执行 confirm()方法,在二阶段回滚执行cancel()方法。

在TCC模式中,Seata框架把每组TCC服务接口当作一个资源(TCC Resource)。这套TCC服务接口可以是RPC,也可以是服务内JVM调用。在业务启动时,Seata框架会自动扫描并识别出TCC服务接口的发布方和调用方:

对于发布方,则Seata框架会在业务启动时向TC注册TCC Resource。与 AT模式的DataSource Resource 一样,每个TCC Resource也会带有一个资源 ID。

对于调用方,则Seata 框架会给其加上切面,在运行时该切面会拦截所有对 TCC 服务接口的调用。每调用一次 try 接口,切面都会先向TC 注册一个分支事务,然后才去执行try()方法的业务逻辑并向TC汇报分支事务状态。

在请求链路调用完成后,发起方通知 TC 提交或回滚分布式事务,进入二阶段调用流程。此时,TC 会根据之前注册的分支事务,回调对应参与者去执行TCC 资源的 confirm() 或 cancel()方法。

Seata TCC 框架本身很简单,主要是扫描TCC服务接口、注册资源、拦截接口调用、注册分支事务、汇报分支事务状态、回调二阶段接口。对于TCC模式来说,最复杂逻辑是TCC服务接口的实现。

TCC 模式与AT模式的主要区别如下。

(1)在使用上,TCC 模式依赖用户自行实现的3个方法(try()、confirm()、cancel())成本较大;AT 模式依赖全局事务注解和代理数据源,代码基本不需要改动,对业务无侵入、接入成本极低。

(2)TCC 模式的作用范围在应用层,本质上是实现针对某种业务逻辑的正向和反向方法;AT模式的作用范围在底层数据源,通过保存操作行记录的前、后镜像和生成反向SQL语句进行补偿操作,对上层应用透明。

(3)TCC模式事务并发控制由业务自行“加锁”,AT模式由Seata框架自动“加锁”

1.举例

以“扣钱”场景为例,在接入 TCC 模式前,对账户“扣钱”,只需一条更新账户余额的 SQL 语句就能完成;但是在接入 TCC 模式之后,用户则需要考虑如何将原来一步就能完成的“扣钱”操作拆成两阶段,实现成3个方法,并且保证如果一阶段try()方法成功则二阶段 confirm()方法也一定能成功。

如下图所示,try()方法在一阶段执行,需要做资源的检查和预留。在“扣钱”场景下,try()方法要做的是检查账户余额是否充足、预留转账资金(预留的方式就是冻结A账户的转账金额)。在try()方法执行后,账户A的余额虽然还是100元,但是其中有30元已经被冻结了,不能被其他事务使用。

二阶段confirm()方法执行真正的“扣钱”操作。confirm()方法会使用try()方法冻结的金额执行账号“扣钱”。在confirm()方法执行后,账户 A 在一阶段中冻结的 30 元已经被扣除,账户 A 的余额变为 70 元 。

如果二阶段是回滚,则需要在cancel()方法内释放一阶段try()方法冻结的 30 元,使账户A回到初始状态,100元全部可用。

Saga模式

Saga理论出自Hector和Kenneth 1987发表的论文SAGAS。

Saga是一种补偿协议。在 Saga 模式中,在分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。

如下图所示,T1~T3都是正向的业务流程,都对应着一个冲正逆向操作C1~C3。

在分布式事务执行过程中,会依次执行各参与者的正向操作。

如果所有正向操作均执行成功,则分布式事务提交。

如果任何一个正向操作执行失败,则分布式事务会退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。

Saga 模式的正向服务与补偿服务也需要业务开发者实现,因此也具有很强的业务侵入性。在Saga 模式中,分布式事务通常是由事件驱动的,在各个参与者之间是异步执行的。

Saga 模式是一种长事务解决方案,适用于业务流程长且需要保证事务最终一致性的业务系统。Saga 模式的一阶段就会提交本地事务,在无锁、长流程情况下这可以保证性能。

Saga模式的优势:

在一阶段提交本地数据库事务,无锁,高性能。

参与者可以采用事件驱动异步执行,高吞吐。

补偿服务即正向服务的“反向”操作,易于理解,易于实现。

Saga模式也存在很明显的缺点:在一阶段已经提交了本地数据库事务,且没有进行“预留”动作,所以不能保证隔离性,不容易进行并发控制。与AT模式和TCC模式相比,Saga 模式的适用场景有限。

XA模式

在XA模式中,需要在Seata定义的分布式事务范围内,利用事务资源(数据库、消息服务等)实现对XA协议的支持,以XA协议的机制来管理分支事务。


XA协议要求事务资源本身提供对规范和协议的支持。因为事务资源(数据库、消息队列)可感知并参与分布式事务处理过程,所以事务资源可以保障从任意视角对数据的访问进行有效隔离,满足全局数据一致性。

本文节选自

《正本清源分布式事务之Seata(全彩)》一书

Seata作者编写,分布式事务处理

欢迎阅读本书了解更多精彩内容!

京东每满100-50,到手价仅需59元

快快扫码抢购吧!

读者评论

相关博文

  • 社区使用反馈专区

    陈晓猛 2016-10-04

    尊敬的博文视点用户您好: 欢迎您访问本站,您在本站点访问过程中遇到任何问题,均可以在本页留言,我们会根据您的意见和建议,对网站进行不断的优化和改进,给您带来更好的访问体验! 同时,您被采纳的意见和建议,管理员也会赠送您相应的积分...

    陈晓猛 2016-10-04
    4725 707 3 7
  • 迎战“双12”!《Unity3D实战核心技术详解》独家预售开启!

    陈晓猛 2016-12-05

    时隔一周,让大家时刻挂念的《Unity3D实战核心技术详解》终于开放预售啦! 这本书不仅满足了很多年轻人的学习欲望,并且与实际开发相结合,能够解决工作中真实遇到的问题。预售期间优惠多多,实在不容错过! Unity 3D实战核心技术详解 ...

    陈晓猛 2016-12-05
    2901 35 0 1
  • czk 2017-07-29
    4726 28 0 1