Seata之AT模式

简介: Seata之AT模式

AT模式的引进

我们XA模式有死锁(协议阻塞)问题:XA prepare 后,分支事务进入阻塞阶段,收到 XA commit 或 XA rollback 前必须阻塞等待。如果没有一个靠谱的协调者存在,比如abc三个库的数据被二阶段决议为提交,此时ab收到的指令,提交后,c库在收到指令后挂了,并没有提交xa事务,或者协调者没有做到二阶段重试,那么这个没有提交的xa事务将会一直 持有锁,造成死锁的局面。在这里我们将会引进AT模式,解决同步阻塞等问题。

seata的AT模式是一个无侵入的分布式事务。

AT模式前提

  • 基于支持本地 ACID 事务的关系型数据库。
  • Java 应用,通过 JDBC 访问数据库。

AT模式的工作流程

AT模式是基于一个全局的事务管理器来管理的。例如,在全局事务下,当我们存在A,B两个服务的时候,A和B的提交都会生成一个undo_log的记录,会记录下执行前和执行后的镜像,如果一段提交没有错误的话,则会进行二段提交,如果在全局事务中有异常抛出,则根据undo_log进行回滚。

阶段一RM的工作:

  • 注册分支事务
  • 记录undo-log(数据快照)
  • 执行业务sql并提交
  • 报告事务状态

阶段二提交时RM的工作:

  • 删除undo-log即可

阶段二回滚时RM的工作:

  • 根据undo-log恢复数据到更新前

案例流程梳理

我们用一个真实的业务来梳理下AT模式的原理。

比如,现在又一个数据库表,记录用户余额:

id money
1 100

其中一个分支业务要执行的SQL为:

update tb_account set money = money - 10 where id = 1

AT模式下,当前分支事务执行流程如下:

一阶段:

(1)TM发起并注册全局事务到TC

(2)TM调用分支事务

(3)分支事务准备执行业务SQL

(4)RM拦截业务SQL,根据where条件查询原始数据,形成快照。

(6)RM执行业务SQL,提交本地事务,释放数据库锁。此时 money = 90

(7)RM报告本地事务状态给TC

二阶段:

(1)TM通知TC事务结束

(2)TC检查分支事务状态

(a)如果都成功,则立即删除快照

(b)如果有分支事务失败,需要回滚。读取快照数据({"id": 1, "money": 100}),将快照恢复到数据库。此时数据库再次恢复为100

AT模式的原理

  • 事务的发起者开始一个全局事务,并在本地事务管理器中开始一个本地事务。
  • 事务的发起者调用其他参与者的服务,将全局事务ID传递给它们。
  • 参与者接收到全局事务ID后,在本地事务管理器中开始一个本地事务,并执行操作。
  • 当参与者的本地事务执行成功时,将操作结果记录在本地日志中。
  • 事务的发起者完成所有参与者的服务调用后,调用各个参与者的提交接口。
  • 参与者检查本地事务的日志记录,如果操作都成功,则提交本地事务;否则,回滚本地事务。

具体使用

修改application.yml文件(每个参与事务的微服务),开启XA模式:

seata:
  data-source-proxy-mode: AT

给发起全局事务的入口方法添加@GlobalTransactional注解:  

    @GlobalTransactional
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(OrderSaveParam orderSaveParam) {
        // 参数校验等必要操作
        // ...
        // 修改库存
        reduceGoodsCount(goodsCountMap);
        // 扣除余额
        reduceMoney(id,money);
        // 异常回滚事务
        int i = 1 / 0;
    }

优缺点

优点

  • 较高的性能:AT模式在每个参与者的本地事务中执行操作,避免了全局锁和阻塞的问题,提高了系统的并发性能。
  • 简化的实现:相对于XA模式,AT模式的实现相对简单,不需要涉及全局事务协调器,减少了开发和维护的复杂性。
  • 本地事务的独立性:每个参与者在本地事务管理器中管理自己的事务,可以独立控制和优化本地事务的执行。

缺点

  • 弱一致性:AT模式对一致性的要求相对较低,可能会出现数据不一致的情况。在某些场景下,可能需要更高的一致性保证,需要考虑其他分布式事务处理模式。
  • 隔离级别限制:由于AT模式依赖于本地事务的隔离性,参与者的隔离级别受限于本地事务管理器支持的隔离级别,可能无法满足某些特定的隔离需求。
  • 容错性和恢复性:AT模式在发生故障或错误时,需要考虑如何处理事务的回滚和恢复,以确保数据的一致性和可靠性。

小结

性能:高

模式:AP,存在数据不一致的中间状态

难易程度:简单,靠SEATA自己解析反向SQL并闻滚

使用要求

  • 所有服务与数据库必须要自己拥有管理权,因为要创建UNDO LOG表

应用场景

  • 高并发互联网应用,允许数据出现短时不一致,可通过对账程序或补录来保证最终一致性。


相关文章
|
6月前
|
自然语言处理 监控 Dubbo
Seata常见问题之使用tcc模式配置yml如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
203 4
|
6月前
|
数据库
|
6月前
|
Java 数据库连接 API
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
127 0
|
5月前
|
Apache 开发者
Apache Seata 如何解决 TCC 模式的幂等、悬挂和空回滚问题
【6月更文挑战第8天】Apache Seata 是一款分布式事务框架,解决TCC模式下的幂等、悬挂和空回滚问题。通过记录事务状态处理幂等,设置超时机制避免悬挂,明确标记Try操作成功来处理空回滚。Seata 提供丰富配置和管理功能,确保分布式事务的可靠性和效率,支持复杂事务处理场景,为企业业务发展提供支持。
211 7
|
6月前
|
存储 Java Nacos
Seata常见问题之xa模式出现错误xid is not valid如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
203 4
|
6月前
|
NoSQL Java 数据库
Seata常见问题之xa模式下插入一条数据再更新这条数据会报错如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
192 2
|
6月前
|
数据库 开发者
Seata的 TCC 模式
Seata的 TCC 模式
|
6月前
|
监控 API 数据库
Seata常见问题之Seata AT的设计不支持使用临时表如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
|
6月前
|
Java 关系型数据库 微服务
Seata常见问题之项目一直启动不成功如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
530 0
|
6月前
|
存储 Java Apache
Seata 的 AT 模式
Seata 的 AT 模式