分布式事务-AT模式

 解决分布式事务,各个子系统之间必须能感知到彼此的事务状态,才能保证状态一致,因此需要一个事务协调者来协调每一个事务的参与者(子系统事务)。这里的子系统事务,称为分支事务;有关联的各个分支事务在一起称为全局事务

名词解析:

  • 全局事务:整个分布式事务
  • 分支事务:分布式事务中包含的每个子系统的事务
  • 最终一致性:各分支事务分别执行并提交,如果有不一致的情况,想办法补偿恢复,达到数据的最终一致性
  • 强一致性:各事务执行完业务不要提交,等待彼此结束,之后统一提交或回滚

AT模式

AT模式是Seata框架中的一种分布式事务解决方案,它利用两阶段提交(2PC)的概念,通过日志记录(在undo_log中)来实现在分布式系统中数据的一致性。AT模式可以解决分布式事务中的数据不一致问题,适合于RPC和微服务架构。 

AT模式是一种无侵入的分布式事务解决方案,在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。
 

一阶段

在一阶段中,Seata会拦截“业务SQL“,首先解析SQL语义,找到要更新的业务数据,在数据被更新前,保存下来"undo",然后执行”业务SQL“更新数据,更新之后再次保存数据”redo“,最后生成行锁,这些操作都在本地数据库事务内完成,这样保证了一阶段的原子性。

二阶段

相对一阶段,二阶段比较简单,负责整体的回滚和提交,如果之前的一阶段中有本地事务没有通过,那么就执行全局回滚,否在执行全局提交,回滚用到的就是一阶段记录的"undo Log",通过回滚记录生成反向更新SQL并执行,以完成分支的回滚。当然事务完成后会释放所有资源和删除所有日志。

AT 模式如何做到对业务的无侵入

一阶段

在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。

以update语句为例:

update user set name = 'name_1' where name = 'name_0'

首先 Seata 的 JDBC数据源代理通过对业务 SQL 解析,提取 SQL 的元数据,也就是得到 SQL 的类型(UPDATE),表(user),条件(where id= 1)等相关的信息。

提取表元数据:

select id,name from user where name = 'name_0'

img

将查询到的结果如上图所示保存为“before image”,执行“业务 SQL”更新业务数据SQL。根据前镜像数据主键查询出后镜像数据,查询结果为:

select id,name from user where id = 1

把业务数据在更新前后的数据镜像组织成回滚日志,将业务数据的更新和回滚日志在同一个本地事务中提交,分别插入到业务表和 UNDO_LOG 表中。

二阶段提交

二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。

二阶段回滚

二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。

总结

AT 模式的一阶段、二阶段提交和回滚均由 Seata 框架自动生成,用户只需编写“业务 SQL”,便能轻松接入分布式事务,AT 模式是一种对业务无任何侵入的分布式事务解决方案。但AT模式存在的不足就是 当操作的数据 是共享型数据,会存在脏写的问题,所以如果是 用户独有数据可以使用AT模式。

AT 模式是一种无侵入的分布式事务解决方案。在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

一阶段

在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。

二阶段提交

二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。

二阶段回滚

二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。

AT 模式的一阶段、二阶段提交和回滚均由 Seata 框架自动生成,用户只需编写“业务 SQL”,便能轻松接入分布式事务,AT 模式是一种对业务无任何侵入的分布式事务解决方案。

1. AT模型特点

(1)低业务侵入

AT模型通过数据源代理可直接在交易流程中接管应用数据操作,并通过SQL自动解析生成日志镜像,实现二阶段操作自动化。在应用开发层面,该模型只需按照正常业务逻辑开展事务调用即可,而无需额外设计开发处理逻辑。

(2)强隔离性

AT模型中设计了特有的全局锁机制,即当第一个并发事务没有完成闭环前,第二个并发事务无法修改数据,从而可以有效防止并发可能造成的事务不一致问题。但与此同时,全局锁机制也牺牲了部分并发事务场景下的性能表现。

2. AT模型运行机制

(1)一阶段

在一阶段,AT模型会拦截SQL,在解析之后提取出类型、表、条件等相关信息,并基于上述信息查询数据表生成前镜像。之后,AT模型将执行SQL语句,并再次查询数据表得到后镜像。最终,前后镜像以及SQL语句将组成一条回滚日志插入到数据库中,该日志相当于为分布式事务加了一层可以随时查阅日志的保险,恢复到SQL语句操作之前的状态。此外,AT模型还会向服务器申请全局锁,从而确保在此分布式事务闭环之前该条数据不会被修改,以保证其隔离性,同时因上述操作将全部在一个本地事务内完成,也保证了一阶段操作的原子性。一阶段流程如图1所示。

图1 一阶段流程

(2)二阶段

二阶段提交流程:如若分布式事务执行成功,则AT模型将会完成最后提交,并自动删除上一阶段申请的全局锁和创建的回滚日志(但事实上,哪怕不删除回滚日志,也不会造成影响)。二阶段提交流程如图2所示。

图2 二阶段提交流程

二阶段回滚流程:如果出于异常原因需要发起回滚,则一阶段保存的前后镜像将会发挥作用,即AT模型会找到之前创建的回滚日志,并对比后镜像与当前数据的差异。如若相同,AT模型会直接使用前镜像的数据,自动发起回滚;如若不同,则说明数据已被其他事务修改,而AT模型对此可给出多种配置方案,如直接抛出异常数据,或选择用前镜像“强行”覆盖当前数据,同时也可以根据业务特点来配置AT模型方案。二阶段回滚流程如图3所示。

图3  二阶段回滚流程

以上即为AT模型两阶段提交的全部过程,其中SQL解析和日志镜像实现了低业务入侵,而全局锁设计则保障了隔离性。

AT 模式作为一种分布式事务解决方案,虽然有很多优点,但也存在一些缺点,具体如下:

性能方面

  • 额外开销:AT 模式在执行过程中需要对 SQL 语句进行解析,记录数据的前后镜像等操作,这会带来一定的性能开销。特别是在高并发场景下,大量的解析和日志记录操作可能会影响系统的整体性能。例如在每秒处理数千笔交易的大型电商系统中,AT 模式的额外开销可能会导致响应时间延长。
  • 资源占用:为了实现事务的一致性,AT 模式可能需要在数据库中临时存储一些事务相关的数据,如回滚日志等,这会占用一定的数据库存储空间和系统资源。当系统处理大量并发事务时,可能会导致数据库的 I/O 压力增大,影响数据库的性能。

一条Update的SQL,则需要全局事务xid获取(与TC通讯)、before image(解析SQL,查询一次数据库)、after image(查询一次数据库)、insert undo log(写一次数据库)、before commit(与TC通讯,判断锁冲突),这些操作都需要一次远程通讯RPC,而且是同步的。另外undo log写入时blob字段的插入性能也是不高的。每条写SQL都会增加这么多开销,粗略估计会增加5倍响应时间。 

兼容性方面

  • 数据库限制:AT 模式对数据库的兼容性有一定要求,它主要适用于支持本地 ACID 事务的关系型数据库,如 MySQL、Oracle 等。对于一些非关系型数据库,如 MongoDB、Cassandra 等,AT 模式可能无法直接适用,因为这些数据库的事务模型和存储结构与关系型数据库有较大差异。
  • 框架适配:AT 模式需要与特定的分布式事务框架(如 Seata)配合使用,在与不同的业务框架或中间件集成时,可能会存在兼容性问题。例如,与某些特殊的数据库连接池或数据访问层框架集成时,可能会出现配置冲突或功能不兼容的情况。

数据一致性方面

  • 网络异常影响:在分布式环境中,网络问题是不可避免的。当网络出现延迟、丢包或故障时,AT 模式可能会出现数据不一致的情况。例如,在事务提交阶段,如果部分节点已经提交成功,但由于网络原因,其他节点未能及时收到提交指令,就可能导致数据不一致。
  • 事务隔离性问题:AT 模式在一定程度上可能会影响事务的隔离性。由于它是基于数据的前后镜像来实现事务的回滚和一致性保证,在某些特殊情况下,可能会出现幻读、不可重复读等问题。比如在一个事务中多次查询同一数据区间,在查询间隔期间,其他事务通过 AT 模式对数据进行了修改并提交,就可能导致当前事务出现不可重复读的情况。


阻塞严重
全局锁的引入实现了隔离性,但带来的问题就是阻塞,降低并发性,尤其是热点数据,这个问题会更加严重。Seata在回滚时,需要先删除各节点的undo log,然后才能释放TC内存中的锁,所以如果第二阶段是回滚,释放锁的时间会更长。
死锁问题
引入全局锁会额外增加死锁的风险,但如果出现死锁,会不断进行重试,最后靠等待全局锁超时,这种方式并不优雅,也延长了对数据库锁的占有时间。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值