Seata-XA模式
1.XA模式是什么
XA规范在上世纪 90 年代初就被提出,用以解决分布式事务处理这个领域的问题
注意:不存在某一种分布式事务机制可以完美适应所有场景,满足所有需求
现在无论AT模式、TCC 模式、Saga 模式,这些模式的提出本质上都源自 XA 规范对某些场景需求的无法满足
XA规范是X/Open组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准
XA规范描述了全局的事务管理器与局部的资源管理器之间的接口。XA规范的目的是允许的多个资源(如数据库,应用服务器,消息队列等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效
XA规范使用两阶段提交(2PC,Two-Phase Commit)来保证所有资源同时提交或回滚。
XA规范在上世纪 90 年代初就被提出。目前几乎所有主流的数据库都对XA规范提供了支持。
DTP模型定义如下角色:
- AP:即应用程序,可以理解为使用DTP分布式事务的程序
- RM:资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库的实例(MySql),通过资源管理器对该数据库进行控制,资源管理器控制着分支事务
- TM:事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理事务生命周期并协调各个RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务。
- DTP模式定义TM和RM之间通讯的接口规范叫XA,简单理解为数据库提供的2PC接口协议,基于数据库的XA协议来实现的2PC又称为XA方案。
案例解释:
应用程序(AP)持有订单库和商品库两个数据源
应用程序(AP)通过TM通知订单库(RM)和商品库(RM),来创建订单和减库存,RM此时未提交事务,此时商品和订单资源锁定
TM收到执行回复,只要有一方失败则分别向其他RM发送回滚事务,回滚完毕,资源锁释放
TM收到执行回复,全部成功,此时向所有的RM发起提交事务,提交完毕,资源锁释放
XA协议的痛点:
如果一个参与全局事务的资源“失联”了(收不到分支事务结束的命令),那么它锁定的数据将一直被锁定。进而甚至可能因此产生死锁。这是 XA 协议的核心痛点,也是Seata引入XA模式要重点解决的问题
2.Seata的事务模式
Seata 定义了全局事务的框架。
全局事务定义为若干分支事务的整体协调:
TM向TC请求发起(Begin)、提交(Commit)、回滚(Rollback)全局事务
TM把代表全局事务的XID绑定到分支事务上
RM向TC注册,把分支事务关联到XID代表的全局事务中
RM把分支事务的执行结果上报给 TC(可选)
TC发送分支提交(Branch Commit)或分支回滚(Branch Rollback)命令给 RM
Seata的全局事务处理过程,分为两个阶段:
- 执行阶段:执行分支事务,并保证执行结果满足是可回滚的(Rollbackable) 和持久化的(Durable)
- 完成阶段:根据执行阶段结果形成的决议,应用通过TM发出全局提交或回滚的请求给 TC,TC命令RM驱动分支事务进行Commit或Rollback
Seata所谓的事务模式是指:运行在Seata全局事务框架下的分支事务的行为模式。准确地讲应该叫作分支事务模式。不同的事务模式区别在于分支事务使用不同的方式达到全局事务两个阶段的目标。即回答以下两个问题:
- 执行阶段:如何执行并保证执行结果满足是可回滚的(Rollbackable) 和持久化的(Durable)
- 完成阶段:收到TC的命令后,如何做到分支的提交或回滚
我们以AT模式举例:
- 执行阶段:
- 可回滚:根据SQL解析结果,记录回滚日志
- 持久化:回滚日志和业务SQL在同一个本地事务中提交到数据库
- 完成阶段:
- 分支提交:异步删除回滚日志记录
- 分支回滚:依据回滚日志进行反向补偿更新
3.Seata的XA模式
在Seata定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对XA协议的支持,以XA协议的机制来管理分支事务的一种事务模式。
- 执行阶段:
- 可回滚:业务SQL操作放在XA分支中进行,由资源对 XA 协议的支持来保证可回滚
- 持久化:XA 分支完成后,执行XA prepare,同样由资源对XA 协议的支持来保证持久化(即,之后任何意外都不会造成无法回滚的情况)
- 完成阶段:
- 分支提交:执行XA分支的 commit
- 分支回滚:执行XA分支的 rollback
为什么要在Seata中增加XA模式呢?支持XA的意义在哪里呢?
本质上Seata已经支持的3大事务模式:AT、TCC、Saga都是补偿型的。
补偿型事务处理机制构建在事务资源之上(要么在中间件层面,要么在应用层面),事务资源本身对分布式事务是无感知的。
事务资源对分布式事务的无感知存在一个根本性的问题:无法做到真正的全局一致性。
比如,一条库存记录处在补偿型事务处理过程中,由100扣减为50。此时仓库管理员连接数据库查询统计库存,就看到当前的50,之后事务因为异外回滚,库存会被补偿回滚为100。显然仓库管理员查询统计到的50就是脏数据。所以补偿型事务是存在中间状态的(中途可能读到脏数据)
XA的价值:
与补偿型不同,XA协议要求事务资源本身提供对规范和协议的支持。
因为事务资源感知并参与分布式事务处理过程,所以事务资源(如数据库)可以保障从任意视角对数据的访问有效隔离,满足全局数据一致性。
比如,刚才提到的库存更新场景,XA事务处理过程中,中间状态数据库存50由数据库本身保证,是不会被仓库管理员的查询统计看到的。除了全局一致性这个根本性的价值外,支持 XA 还有如下几个方面的好处:
- 业务无侵入:和AT一样,XA模式是业务无侵入的,不给应用设计和开发带来额外负担。
- 数据库的支持广泛:XA协议被主流关系型数据库广泛支持,不需要额外的适配即可使用。
- 多语言支持容易:因为不涉及SQL解析,XA模式对Seata的RM的要求比较少。
- 传统基于XA应用的迁移:传统的基于XA协议的应用,迁移到Seata平台,使用XA模式将更平滑。
4.XA模式使用
我们从官方案例入手,具体的官方案例下载地址:https://github.com/seata/seata-samples
官方案例演示图:
案例解析:
5.总结
在当前的技术发展阶段,不存一个分布式事务处理机制可以完美满足所有场景的需求。
一致性、可靠性、易用性、性能等诸多方面的系统设计约束,需要用不同的事务处理机制去满足。
Seata项目最核心的价值在于:构建一个全面解决分布式事务问题的标准化平台。
基于Seata,上层应用架构可以根据实际场景的需求,灵活选择合适的分布式事务解决方案。
XA 模式的加入,补齐了Seata在全局一致性场景下的缺口,形成 AT、TCC、Saga、XA四大事务模式的版图,基本可以满足所有场景的分布式事务处理诉求。