Seata四种事务模式AT、TCC、SAGA 、 XA详解

文章目录

  • 一、 @GlobalTransactional
  • 一、AT模式
    • 1、原理
    • 2 、优缺点
    • 3、实现
  • 二、TCC模式
    • 1、原理
    • 2 、优缺点
    • 3、实现
  • 三、SAGA模式
    • 1 、原理
    • 2 、优缺点
    • 3 、实现
  • 四、XA模式
    • 1 、原理
    • 2 、优缺点
    • 3、 实现
  • 五、 四种模式对比

我们知道Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA四种事务模式,为用户打造一站式的分布式解决方案,包括事务管理、本地事务协调、分布式事务日志和分布式锁等组件。

之前我们学习了Seata的简介、Seata客户端和服务端的搭建集成、本篇文章我们了解一下Seata是如何通过四种事务模式解决分布式事务问题的。

一、 @GlobalTransactional

Spring本地事务使用:@Transactional
Seata全局事务使用:@GlobalTransactional

继续以我们之前搭建的用户购买商品微服务系统【微服务整合Seata1.5.2+Nacos2.2.1+SpringBoot】为例:
仓储服务(Stock):对给定的商品扣除仓储数量。
订单服务(Order):根据采购需求创建订单。
账户服务(Account):从用户账户中扣除余额。

创建订单->调用库存服务扣减库存->调用账户服务扣减账户余额->修改订单状态
简单说:下订单->扣库存->减余额->改状态

假设第3步扣减账户超时,在seata-account-service项目中模拟一个异常。不加 @GlobalTransactional 事务控制出现超时会数据异常,当库存和账户金额扣减后,订单状态并没有设置为已经完成,没有从零改为 1。而且由于 feign 的重试机制,账户余额还有可能被多次扣减。

在这里插入图片描述
接下来加上加 @GlobalTransactional,注意每个应用都使用Seata对数据源进行代理,再次请求,发现全局事务回滚成功。

/*** 使用Seata对数据源进行代理*/
@Configurationpublic class DataSourceProxyConfig {@Value("${mybatis-plus.mapper-locations}")private String mapperLocations;@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource druidDataSource(){return new DruidDataSource();}@Beanpublic DataSourceProxy dataSourceProxy(DataSource dataSource) {return new DataSourceProxy(dataSource);}@Beanpublic SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSourceProxy);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());return sqlSessionFactoryBean.getObject();}
}

在这里插入图片描述

如果未成功,先检查异常是否被catch或者有无熔断降级。

一、AT模式

1、原理

AT模式前提:
基于支持本地 ACID 事务的关系型数据库。
Java 应用,通过 JDBC 访问数据库。

两阶段提交协议的演变
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。

AT模式是一种分布式事务处理模式,它通过在每个参与者的本地事务中实现事务的原子性和隔离性,来保证分布式事务的一致性。AT模式避免了全局锁和阻塞的问题,从而提高了系统的并发性能。在AT模式中,参与者的本地事务执行成功后即可提交,而不需要等待其他参与者的状态。

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

seata的AT模式:Seata的AT模式是在AT模式基础上进行了扩展和优化的实现。Seata引入了Seata Server和Seata Client的概念,通过Seata Server作为事务协调器,集中管理分布式事务的控制逻辑。Seata的AT模式还提供了更多的功能和工具,如分布式事务日志和分布式锁,以增强分布式事务的可靠性和性能。

2 、优缺点

优点

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

缺点

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

3、实现

添加配置seata:data-source-proxy-mode: AT
在需要分布式事务的业务代码上添加注解@GlobalTransactional
重启测试

二、TCC模式

1、原理

TCC模式是一种分布式事务处理模式,用于解决分布式环境下的一致性问题。它通过将事务分解为三个阶段(Try、Confirm、Cancel)来实现事务的可靠性和一致性。使得每个参与者可以控制自己的操作和资源,从而实现了分布式事务的可靠性和一致性。它要求参与者实现相应的接口和逻辑,确保Try和Cancel操作是幂等的,以处理重试和故障恢复情况。

AT 模式与TCC 模式
AT 模式(参考链接 TBD)基于 支持本地 ACID 事务 的 关系型数据库:
一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。
相应的,TCC 模式,不依赖于底层数据资源的事务支持:
一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
二阶段 commit 行为:调用 自定义 的 commit 逻辑。
二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

TCC模式的工作原理如下

Try阶段(尝试阶段):在这个阶段,参与者(服务)尝试预留或锁定资源,并执行必要的前置检查。如果所有参与者的Try操作都成功,表示资源可用,并进入下一阶段。如果有任何一个参与者的Try操作失败,表示资源不可用或发生冲突,事务将中止。

Confirm阶段(确认阶段):在这个阶段,参与者进行最终的确认操作,将资源真正提交或应用到系统中。如果所有参与者的Confirm操作都成功,事务完成,提交操作得到确认。如果有任何一个参与者的Confirm操作失败,事务将进入Cancel阶段。

Cancel阶段(取消阶段):在这个阶段,参与者进行回滚或取消操作,将之前尝试预留或锁定的资源恢复到原始状态。如果所有参与者的Cancel操作都成功,事务被取消,资源释放。如果有任何一个参与者的Cancel操作失败,可能需要进行补偿或人工介入来恢复系统一致性。

seata的TCC模式:Seata的TCC模式是在TCC模式基础上进行了扩展和优化的实现。Seata引入了Seata Server作为事务协调器,集中管理分布式事务的控制逻辑。Seata的TCC模式还提供了分布式事务日志和分布式锁等功能,以增强事务的可靠性和性能。Seata的TCC模式可以更方便地集成到应用中,并提供了更好的事务管理和监控能力。

2 、优缺点

优点

  • 一阶段完成直接提交事务,释放数据库资源,性能好;
  • 相比AT模型,无需生成快照,无需使用全局锁,性能最强;
  • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库;

缺点

  • 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
  • 软状态,事务是最终一致;
  • 需要考虑Confirm和Cancel的失败情况,做好幂等处理;

3、实现

以账户转账为例:

定义参与者接口:

public interface AccountService {
boolean tryTransfer(String fromAccount, String toAccount, double amount);
boolean confirmTransfer(String fromAccount, String toAccount, double amount);
boolean cancelTransfer(String fromAccount, String toAccount, double amount);
}

实现参与者逻辑:

public class AccountServiceImpl implements AccountService {
@Override
public boolean tryTransfer(String fromAccount, String toAccount, double amount) {
// 执行转账操作,预留转出账户金额,检查账户余额等
// 如果成功,返回 true;如果失败,返回 false
}
@Override
public boolean confirmTransfer(String fromAccount, String toAccount, double amount) {
// 确认转账操作,将预留金额转出
// 如果成功,返回 true;如果失败,返回 false
}
@Override
public boolean cancelTransfer(String fromAccount, String toAccount, double amount) {
// 取消转账操作,将预留金额回滚到账户
// 如果成功,返回 true;如果失败,返回 false
}
}

客户端调用:

// 获取Seata全局事务ID
String xid = RootContext.getXID();
// 开启全局事务
TransactionContext context = new TransactionContext();
context.setXid(xid);
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
try {
// 调用参与者的tryTransfer方法
boolean tryResult = accountService.tryTransfer(fromAccount, toAccount, amount);
if (tryResult) {
// 提交全局事务
tx.commit();
} else {
// 回滚全局事务
tx.rollback();
}
} catch (Exception e) {
// 异常时回滚全局事务tx.rollback();
}

三、SAGA模式

1 、原理

Saga模式是一种用于处理分布式事务的模式,它通过将长时间的、复杂的事务分解为多个小的、可逆的事务片段,以实现事务的一致性和可靠性。

在Saga模式中,每个事务片段称为一个补偿操作。每个补偿操作都与一个正向操作相对应,正向操作是事务的一部分,而补偿操作是用于撤销或修复正向操作的。Saga模式通过按照事务执行的顺序,依次执行正向操作和补偿操作,来确保事务在发生失败或异常时能够进行回滚或恢复。

Saga模式的执行过程如下

执行正向操作:按照事务的逻辑顺序,依次执行正向操作。每个正向操作都会记录事务的执行状态。
如果所有的正向操作都成功执行,则事务提交完成。
如果某个正向操作失败,将会触发相应的补偿操作。补偿操作会撤销或修复正向操作的影响。
执行补偿操作:按照逆序依次执行已经触发的补偿操作。补偿操作应该具备幂等性,以便可以多次执行而不会造成副作用。
如果所有的补偿操作都成功执行,则事务回滚完成。
如果补偿操作也失败,需要人工介入或其他手段来解决事务的一致性问题。

Seata的Saga模式
  Seata的Saga模式通过Seata框架来管理和协调分布式事务,提供了对事务的编排和状态管理的支持。它与Seata的其他特性(如AT模式、TCC模式)结合在一起,构成了Seata全面的分布式事务解决方案。

Seata的Saga模式相对于传统的Saga模式,具有以下特点

  • 集成性:Seata的Saga模式与Seata框架紧密集成,可以与Seata的其他特性一起使用,如分布式事务日志和分布式锁等。
  • 强一致性:Seata的Saga模式提供了强一致性的事务支持,确保事务的执行顺序和一致性。
  • 可靠性:Seata的Saga模式在补偿操作的执行过程中,支持重试和恢复机制,提高了事务的可靠性和恢复能力。

适用场景

业务流程长、业务流程多

参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口

2 、优缺点

优点

  • 一阶段提交本地事务,无锁,高性能
  • 事件驱动架构,参与者可异步执行,高吞吐
  • 补偿服务易于实现,不用编写TCC中的三个阶段,实现简单

缺点

  • 没有锁,不保证隔离性,会有脏写;
  • 软状态持续时间不确定,时效性差;

3 、实现

使用Seata的Saga模式,需要进行以下步骤:

定义参与者接口:

public interface OrderService {
boolean createOrder(String orderId, String userId, String productId, int quantity);
boolean cancelOrder(String orderId);
}
public interface ProductService {
boolean reduceStock(String productId, int quantity);
boolean revertStock(String productId, int quantity);
}

实现参与者逻辑:

public class OrderServiceImpl implements OrderService {
@Override
public boolean createOrder(String orderId, String userId, String productId, int quantity) {
// 执行订单创建逻辑,如创建订单记录、扣减用户余额等
// 如果成功,返回 true;如果失败,返回 false
}
@Override
public boolean cancelOrder(String orderId) {
// 执行订单取消逻辑,如回滚订单记录、恢复用户余额等
// 如果成功,返回 true;如果失败,返回 false
}
}
public class ProductServiceImpl implements ProductService {
@Override
public boolean reduceStock(String productId, int quantity) {
// 执行减少库存逻辑,如更新产品库存、记录库存变更日志等
// 如果成功,返回 true;如果失败,返回 false
}
@Override
public boolean revertStock(String productId, int quantity) {
// 执行恢复库存逻辑,如恢复产品库存、删除库存变更日志等
// 如果成功,返回 true;如果失败,返回 false}
}

客户端调用:

// 获取Seata全局事务ID
String xid = RootContext.getXID();
// 开启全局事务
TransactionContext context = new TransactionContext();
context.setXid(xid);
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
try {
// 调用参与者的方法
boolean createOrderResult = orderService.createOrder(orderId, userId, productId, quantity);boolean reduceStockResult = productService.reduceStock(productId, quantity);
if (createOrderResult && reduceStockResult) {
// 提交全局事务tx.commit();
} else {
// 回滚全局事务
tx.rollback();
}
} catch (Exception e) {// 异常时回滚全局事务tx.rollback();
}

四、XA模式

1 、原理

XA模式是一种分布式事务处理的协议,它使用两阶段提交(2PC)来保证事务的一致性和可靠性。

准备阶段:事务协调器向参与者发送准备请求,要求它们准备执行事务操作,并将结果记录在事务日志中。
提交阶段:如果所有参与者都准备就绪,事务协调器发送提交请求给参与者,要求它们执行事务的提交操作。
中断阶段:如果任何一个参与者未能准备就绪或发生错误,事务协调器发送中断请求给参与者,要求它们执行事务的中断操作。

通过两阶段提交,XA模式确保所有参与者要么一起提交事务,要么一起中断事务,从而保证事务的一致性。然而,XA模式也存在一些问题,如阻塞和单点故障的风险,因此在某些情况下可能需要考虑其他分布式事务解决方案。

2 、优缺点

优点

  • 一致性:XA模式通过两阶段提交协议,确保所有参与者要么一起提交事务,要么一起中断事务,从而保证事务的一致性。
  • 可靠性:XA模式提供了强一致性和可靠性的保证,在分布式环境下可以确保事务的正确执行。
  • 标准化:XA模式是一种标准的分布式事务处理协议,被广泛支持和应用于各种数据库和资源管理器中。

缺点

  • 性能开销:在XA模式中,需要进行多次网络通信和协调操作,这会引入额外的性能开销,并且可能会导致事务处理的延迟增加。
  • 阻塞风险:在准备阶段和提交阶段,所有的参与者都需要等待事务协调器的指令,这可能导致一些参与者在等待期间被阻塞,影响系统的吞吐量和并发性能。
  • 单点故障:在XA模式中,事务协调器起着关键的角色,如果事务协调器出现故障,整个分布式事务系统可能无法正常运行。

3、 实现

添加配置seata:data-source-proxy-mode: XA
在需要分布式事务的业务代码上添加注解@GlobalTransactional
从编程模型上,XA 模式与 AT 模式保持完全一致。只需要修改数据源代理,即可实现 XA 模式与 AT 模式之间的切换。
重启测试

五、 四种模式对比

XAATTCCSAGA
一致性强一致弱一致弱一致最终一致
隔离性完全隔离基于全局锁隔离基于资源预留隔离无隔离
代码侵入有,需要编写三个接口有,需要编写状态机和补偿业务
性能非常好非常好
场景对一致性、隔离性有高要求的业务基于关系型数据库的大多数分布式务场景都可以1.对性能要求较高的事务;
2.有非关系型数据库要参与的事务;
1.业务流程长、业务流程多;
2.参与者包含其它公司或遗留系统服务,无法提供TCC模式要求的三个接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/111730.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebGoat搭建和Yakit学习

环境搭建 jdk版本:openjdk version "17.0.5“ WebGoat版本:webgoat-server-8.1.0.jar 环境不同有很大可能不能搭建成功 运行命令:java -jar webgoat-server-8.1.0.jar --server.port8888 --server.address192.168.142.131 搭建完成后…

电脑网速慢怎么解决?推荐这3个方法

在数字化时代,快速的互联网连接对于工作和娱乐都至关重要。然而,有时候我们可能会遇到电脑网速慢的问题,这会影响我们的效率和体验。可是电脑网速慢怎么解决呢?本文将介绍解决电脑网速慢的3个方法,帮助你提升网络连接的…

面经pc端项目

创建项目 安装脚手架-----创建项目------选择自定义 sass基础语法 https://www.sass.hk/ sass语法有两个:sass(旧) scss(新) 1.scss语法 和less语法类似,支持嵌套,支持变量… scss: $变量名 less: @变量名 $color:orange; .box{width: 400px;height: 400px;borde…

如何使用反 CSRF 令牌保护您的网站和 Web 应用程序

防止跨站点请求伪造攻击 (CSRF/XSRF)的最常见方法是使用反 CSRF 令牌,该令牌只是一个唯一值集,然后由 Web 应用程序需要。CSRF 是一种客户端攻击,可用于将用户重定向到恶意网站、窃取敏感信息或在用户会话中执行其他操作。幸运的是&#xff0…

python萌新爬虫学习笔记【建议收藏】

文章目录 1. 如何何请求解析url2. 如何获取标签里面的文本3. 如何解析JSON格式4. 如何添加常用的header5. 如何合并两个div6. 如何删除html dom的部分结构7. 如何一次性获取所有div标签里的文本8. python爬虫如何改变响应文本字符集编码9. 如何进行字符集转码11. response.text…

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出 目录 多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向…

华为云云服务器云耀L实例评测 | 智能不卡顿:如何实现流畅的业务运行

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

flink的几种常见的执行模式

背景 在运行flink时,我们经常会有几种不同的执行模式,比如在IDE中启动时,通过提交到YARN上,还有通过Kebernates启动时,本文就来记录一下这几种模式 flink的几种执行模式 flink嵌入式模式: 这是一种我们在…

黑马JVM总结(十四)

(1)分代回收_1 Java虚拟机都是结合前面几种算法,让他们协同工作,具体实现是虚拟机里面一个叫做分代的垃圾回收机制,把我们堆内存大的区域划分为两块新生代、老年代 新生代有划分为伊甸园、幸存区Form、幸存区To 为什…

迅为RK3399开发板创建android工程

打开 AndroidStudio 软件,点击“Start a new Android Studio project”新建一个 Native C工程(因为我们要调用本地库,所以要创建这个 C实例工程),点击“Next” 2.填写创建信息,如下图所示。最后点击“finis…

计算机网络中的应用层和传输层(http/tcp)

目录 1、协议的通俗理解 1.1 理解协议 2.应用层 2.1 http协议 2.2 HTTP的方法 2.3 HTTP的状态码 2.4 HTTP常见Header 3、传输层 3.1 端口号 3.1.1 端口号范围划分 3.1.2 netstat 3.1.3 认识知名端口号(Well-Know Port Number) 3.2 UDP协议 3.2.1 UDP协议端格式 3…

本地Tomcat网页搭建结合Cpolar内网穿透实现公网访问

文章目录 1.前言2.本地Tomcat网页搭建2.1 Tomcat安装2.2 配置环境变量2.3 环境配置2.4 Tomcat运行测试2.5 Cpolar安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 Tomcat作为一个轻量级的服务器,不仅名字很有趣&#…