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

news2024/11/22 21:46:58

文章目录

  • 一、 @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对数据源进行代理
 */
@Configuration

public class DataSourceProxyConfig {
        @Value("${mybatis-plus.mapper-locations}")
        private String mapperLocations;

        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource druidDataSource(){
            return new DruidDataSource();
        }

        @Bean
        public DataSourceProxy dataSourceProxy(DataSource dataSource) {
            return new DataSourceProxy(dataSource);
        }

        @Bean
        public 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.coloradmin.cn/o/1019587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode75】第五十八题 组合总和Ⅲ

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目让我们找出长度为k并且总和为n的所有组合,我们能用的元素只有1~9。 那么这种要求排列组合的题,基本是是离不…

2023客服管理者面临的挑战

客服管理者在当今的数字化时代也面临着许多挑战。以下是一些主要的挑战: 同行业竞争加剧:客服行业面临着来自同行业的竞争压力。为了获得竞争优势,企业需要不断提高自身的产品和服务质量,同时还需要不断降低成本、提高效率。然而…

go调用so库

来源:微信公众号「编程学习基地」 文章目录 go调用so库生成so库调用so库 go调用so库 生成so库 load_so.h #ifndef _LOAD_SO_H #define _LOAD_SO_Hint do_test_so_func(int a,int b);#endif load_so.c #include "load_so.h"int do_test_so_func(int …

数据结构——四叉树

四叉树(Quadtree)是一种用于表示和管理二维空间的树状数据结构。它将二维空间递归地分割成四个象限,每个象限可以继续分割,以实现对空间的更精细的划分。四叉树通常用于解决空间搜索和查询问题,例如碰撞检测、图像压缩…

vector使用和模拟实现

💓博主个人主页:不是笨小孩👀 ⏩专栏分类:数据结构与算法👀 C👀 刷题专栏👀 C语言👀 🚚代码仓库:笨小孩的代码库👀 ⏩社区:不是笨小孩👀 🌹欢迎大…

2.6W字系统总结,带你实现 Linux 自由!

以前就聊过大多数应届生入职后会遇到的两大拦路虎分别是Git和Linux,其中关于Git,前段时间已经分享过自己工作两年多以来用过的比较实用的一些命令了,这些命令可能不是最花哨的,但绝对是最实用的。 今天分享一份很全面的Linux常用…

springboot+canal+mysql+redis缓存双写一致性

canal官网地址:https://github.com/alibaba/canal/wiki/QuickStart 基本上按照官网的步骤来就行 准备 首先服务器上要安装好jdk,因为canal运行需要jdk,同时把canal对应的端口在服务中开放,否则连接不上 对于自建 MySQL , 需要先开启 Binl…

linux安装python3.x版本

linux安装python3.x版本 ① 安装依赖环境② 下载python版本包③ 安装python④ 建立软链接⑤ 加入path⑥ 验证 官网版本地址:https://www.python.org/ftp/python/ ① 安装依赖环境 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel…

Vue 使用vue-pdf 显示pdf文件 切换页面 缩放 全屏 自动播放等

<template><div id"container"><!-- 上一页、下一页--><div class"right-btn"><div click"toFullOrExit" class"turn-btn"><span>{{ isFull 1 ? "取消全屏" : "全屏" }}&l…

GLTF-pipeline

gltf-pipeline可用作命令行工具或 Node.js 模块。 开始 安装 Node.js如果还没有&#xff0c;然后&#xff1a; npm install -g gltf-pipeline使用 gltf-pipeline 作为命令行工具&#xff1a; 将 glTF 转换为 glb gltf-pipeline -i model.gltf -o model.glb gltf-pipeline…

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

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

骨髓小游戏

欢迎来到程序小院 骨髓 玩法&#xff1a; 骨髓推塔小游戏&#xff0c;敌方士兵进入到我方高塔会毁坏建筑&#xff0c;我方可派兵前去迎战&#xff0c;我方&#xff1a;骑兵、长枪兵、弓兵、敌法&#xff1a;骷髅骑兵、骷髅长枪兵、 骷髅弓兵,快去消灭敌人吧^^。开始游戏https:…

利用爬虫技术自动化采集汽车之家的车型参数数据

导语 汽车之家是一个专业的汽车网站&#xff0c;提供了丰富的汽车信息&#xff0c;包括车型参数、图片、视频、评测、报价等。如果我们想要获取这些信息&#xff0c;我们可以通过浏览器手动访问网站&#xff0c;或者利用爬虫技术自动化采集数据。本文将介绍如何使用Python编写…

flutter开发实战-长按TextField输入框cut、copy设置为中文复制、粘贴

flutter开发实战-长按TextField输入框cut、copy设置为中文复制、粘贴 在开发过程中&#xff0c;需要长按TextField输入框cut、copy设置为中文“复制、粘贴”&#xff0c;这里记录一下设置的代码。 一、pubspec.yaml设置flutter_localizations 在pubspec.yaml中设置flutter_l…

教你制作简单的洪水淹没模型

制作思路&#xff1a; 利用GIS软件将地形图通过高程垂直夸大&#xff0c;显示出其地形地貌&#xff0c;绘制一个面&#xff0c;使面从下向上移动&#xff0c;因地形高程的不同&#xff0c;面穿过地形图的面积不同&#xff0c;从而视觉上模拟出了水淹没的过程。 前期准备&…

facechain环境部署

环境安装 # 创建虚拟环境facechain conda create -n facechain python3.8 conda activate facechain # 克隆 GIT_LFS_SKIP_SMUDGE1 git clone https://github.com/modelscope/facechain.git --depth 1 # 安装第三方库 cd facechain pip install -r requirements.txt pip insta…

【JavaEE】操作系统内核中的进程

文章目录 &#x1f490;什么叫做进程&#x1f490;进程在系统中是如何进行管理的&#x1f490;PCB中一些比较重要的属性&#x1f490;进程持有的CPU资源——进程调度&#x1f490;内存分配——内存管理 &#x1f490;什么叫做进程 进程概念&#xff1a;一个已经跑起来的程序就…

Scrum和Kanban方法的结合:Scrumban的实施指南

如果没有有效的项目管理&#xff0c;团队成员将不得不处理尽可能多的程序&#xff0c;而这种方法不会导致成功。有几种著名的项目管理方法&#xff0c;例如 Scrum 和看板。但是有一种方法可以结合他们的最佳实践。 Scrum 和看板的优势结合在称为 Scrumban 的混合方法中。它非常…

chales 重写/断点/映射/手机代理/其他主机代理

1 chales 安装和代理配置/手机代理配置/电脑代理配置 chales 安装和代理配置/手机代理配置/电脑代理配置 2 转载:Charles Rewrite重写(详解&#xff01;必懂系列) Charles Rewrite重写(详解&#xff01;必懂系列) 1.打开charles&#xff0c;点击菜单栏的Tools选中Rewrite2.…

企业架构LNMP学习笔记59

目录介绍&#xff1a; bin&#xff1a;存放的是启动和关闭tomcat的脚本文件&#xff1b; conf&#xff1a;存放tomcat服务器的各种全局配置文件&#xff0c;其中最重要的是server.xml和web.xml lib: 存放的是tomcat服务器所需要的各种jar文件。java打包类库。 logs&#xff…