中间件之Seata
一、引言
在微服务架构日益盛行的今天,分布式事务成为了一个必须面对和解决的问题。传统的本地事务已经无法满足分布式环境下的数据一致性需求,因此分布式事务解决方案应运而生。Seata作为一款开源的分布式事务中间件,以其高性能、易用性和灵活性受到了广泛的关注和应用。本文将对Seata进行全面深入的解析,包括其基本概念、事务模式、工作原理、代码示例以及实际应用场景,旨在帮助开发者更好地理解和使用Seata。
二、Seata概述
2.1 基本概念
Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。Seata通过提供全局事务管理和协调服务,支持多种主流的数据库和RPC框架,以及Spring Cloud和Dubbo等微服务框架。Seata的设计目标是解决分布式事务的一致性问题,实现高可用、高性能、易扩展的分布式事务管理。
2.2 角色与组件
Seata主要由三个核心角色组成:
TC (Transaction Coordinator):
事务协调器,维护全局和分支事务的状态,驱动全局事务提交或回滚。TC是单独部署的Server服务端。
TM (Transaction Manager):
事务管理器,控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。TM和RM都是嵌入到应用中的Client客户端。
RM (Resource Manager):
资源管理器,管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
三、Seata的事务模式
Seata支持四种分布式事务模式:AT模式、TCC模式、Saga模式和XA模式,每种模式都有其独特的适用场景和优缺点。
3.1 AT模式
3.1.1 概念与原理
AT模式(Automatic Transaction)是Seata创新的一种非侵入式的分布式事务解决方案。在AT模式下,用户只需关心自己的“业务SQL”,Seata框架会自动生成事务的二阶段提交和回滚。
AT模式的工作原理如下:
一阶段:
Seata会拦截“业务SQL”,首先解析SQL语义,找到“业务SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
二阶段提交:
如果全局事务提交,Seata不会执行任何操作,因为一阶段已经完成数据的持久化。
二阶段回滚:
如果全局事务回滚,Seata会根据“before image”和“after image”生成反向的SQL语句,并执行这些反向SQL语句来撤销一阶段的业务数据变更。
3.1.2 优缺点
优点:
简化编程模型:
对业务代码无侵入性,可以在不修改业务逻辑的情况下实现分布式事务。
高性能:
通过异步通信和批量处理等手段,提高了分布式事务的性能。
缺点:
数据一致性风险:
在极端情况下(如数据库宕机),可能会出现数据一致性风险。
不支持跨数据库事务:
AT模式主要适用于单个数据库的事务管理,对于跨数据库的事务支持有限。
3.1.3 代码示例
以下是一个使用Seata AT模式实现分布式事务的简单示例,假设有两个微服务:订单服务和库存服务,订单服务负责创建订单,库存服务负责扣减库存。当用户下单时,需要同时调用两个服务,并保证数据一致性。
// 订单服务代码示例
@GlobalTransactional
public void createOrder(Order order) {// 调用库存服务扣减库存inventoryService.decreaseStock(order.getCommodityCode(), order.getCount());// 创建订单orderMapper.insert(order);
}// 库存服务代码示例
@GlobalTransactional
public void decreaseStock(String commodityCode, int count) {// 扣减库存storageMapper.updateStock(commodityCode, count);
}
在上述代码中,通过在createOrder
和decreaseStock
方法上添加@GlobalTransactional
注解,Seata会自动管理这两个方法之间的事务一致性。
3.2 TCC模式
3.2.1 概念与原理
TCC模式(Try-Confirm-Cancel)是Seata支持的一种由业务方细粒度控制的侵入式分布式事务解决方案。TCC模式将分布式事务拆分为Try、Confirm和Cancel三个阶段,每个阶段都需要业务方自行实现。
Try阶段:
执行业务的预备操作,完成资源的检查和预留。如果预备操作成功,则返回try成功状态;如果预备操作失败,则返回try失败状态。
Confirm阶段:
在Try阶段成功执行后,执行业务的确认操作,完成资源的最终提交。Confirm阶段必须保证幂等性,即无论执行多少次,结果都是一样的。
Cancel阶段:
在Try阶段成功执行后,如果全局事务需要回滚,则执行业务的取消操作,释放Try阶段预留的资源。Cancel阶段也必须保证幂等性。
3.2.2 优缺点
优点:
灵活性高:
TCC模式允许业务方细粒度地控制事务的每个阶段,可以适应复杂的业务场景。
性能优越:
TCC模式在第一阶段只锁定必要的资源,减少了资源锁持有时间,提高了并发性能。
缺点:
业务侵入性强:
TCC模式需要业务方实现Try、Confirm和Cancel三个阶段的操作,增加了业务代码的复杂度。
实现难度大:
需要保证Try、Confirm和Cancel三个阶段的幂等性,以及处理各种异常情况,实现难度较大。
3.2.3 代码示例
以下是一个使用Seata TCC模式实现分布式事务的示例:
// TCC接口定义
public interface TccActionOne {@TwoPhaseBusinessAction(name = "DubboTccActionOne", commitMethod = "commit", rollbackMethod = "rollback")public boolean prepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "a") String a);public boolean commit(BusinessActionContext actionContext);public boolean rollback(BusinessActionContext actionContext);
}// TCC接口实现
@Service
public class TccActionOneImpl implements TccActionOne {@Overridepublic boolean prepare(BusinessActionContext actionContext, String a) {// 执行业务的预备操作// ...return true; // 返回try成功状态}@Overridepublic boolean commit(BusinessActionContext actionContext) {// 执行业务的确认操作// ...return true; // 返回commit成功状态}@Overridepublic boolean rollback(BusinessActionContext actionContext) {// 执行业务的取消操作// ...return true; // 返回rollback成功状态}
}
在上述代码中,TccActionOne
接口定义了Try、Confirm和Cancel三个阶段的操作,TccActionOneImpl
类实现了这些操作。业务方需要在每个阶段中编写相应的业务逻辑,并保证这些逻辑的幂等性。
3.3 Saga模式
3.3.1 概念与原理
Saga模式是一种长事务模式,它将一个长事务拆分成多个小事务,每个小事务都是一个短事务。Saga模式的核心思想是补偿,即如果某个小事务失败了,可以通过回滚之前的小事务来保证整个长事务的正确性。
Saga模式的工作原理如下:
- 正向执行:依次执行每个小事务,如果所有小事务都执行成功,则长事务成功。
- 逆向补偿:如果某个小事务执行失败,则依次执行之前所有成功小事务的补偿操作,直到所有小事务都回滚到初始状态。
3.3.2 优缺点
优点:
适用于长事务:
Saga模式特别适用于需要跨多个服务或数据库完成的长事务。
业务侵入性较低:
Saga模式只需要业务方实现正向和反向两个操作,相对于TCC模式来说侵入性较低。
缺点:
补偿操作的复杂性:
在复杂业务场景下,补偿操作可能很难实现,且容易出现补偿失败的情况。
数据一致性风险:
在极端情况下(如网络分区),可能会出现数据一致性风险。
3.3.3 代码示例
以下是一个使用Seata Saga模式实现分布式事务的示例:
// 伪代码示例 // 定义一个服务接口,包含正向服务和补偿服务
interface SagaService { void execute(); // 正向服务 void compensate(); // 补偿服务
} // 实现Saga服务
class OrderService implements SagaService { @Override public void execute() { // 执行订单创建的正向逻辑 } @Override public void compensate() { // 执行订单创建的补偿逻辑 }
} class PaymentService implements SagaService { @Override public void execute() { // 执行支付的正向逻辑 } @Override public void compensate() { // 执行支付的补偿逻辑 }
} // Saga协调器
class SagaCoordinator { public void executeSaga(List<SagaService> services) { for (SagaService service : services) { try { service.execute(); // 执行正向服务 } catch (Exception e) { // 出现异常时,回滚已执行的服务 for (int i = services.indexOf(service) - 1; i >= 0; i--) { services.get(i).compensate(); } throw e; // 抛出异常,中断流程 } } // 所有服务执行成功,提交事务 }
} // 使用示例
public class SagaExample { public static void main(String[] args) { List<SagaService> services = Arrays.asList(new OrderService(), new PaymentService()); SagaCoordinator coordinator = new SagaCoordinator(); try { coordinator.executeSaga(services); } catch (Exception e) { System.err.println("Saga execution failed: " + e.getMessage()); } }
}
3.4 XA模式
3.4.1 概念与原理
执行阶段:
RM(资源管理器)将分支事务注册到全局事务协调器(TC)。
RM执行分支业务操作,但不提交。这确保了分支事务不会立即生效,等待全局协调后再决定是否提交。
RM报告分支事务执行状态给TC。
完成阶段:
TC检测各个分支事务的执行状态。
如果所有分支事务都成功,TC通知所有RM提交事务,即提交所有分支事务的更改。
如果有任何分支事务失败,TC通知所有RM回滚事务,即回滚所有分支事务的更改。
RM接收来自TC的指令,根据指令来提交或回滚分支事务。
3.4.2 优缺点
优点
- 保证了数据的强一致性,满足ACID原则。
- 几乎所有主流的数据库都支持XA协议,实现简单。
- 没有代码侵入,开发者无需修改业务代码。
缺点
- 性能较差,因为一阶段需要锁定数据库资源,等待二阶段结束才释放。
- 依赖关系型数据库实现事务,不适用于非关系型数据库。
- 存在单点问题,全局事务协调器可能成为系统瓶颈。
3.4.3 代码示例
XA模式的代码实现涉及Seata的配置和事务注解的使用。以下是一个简化的代码示例,展示了如何在Spring Boot项目中使用Seata的XA模式:
// 引入Seata依赖(在pom.xml中)
<dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>你的Seata版本</version>
</dependency> // 配置文件(application.yml)
seata: enabled: true data-source-proxy-mode: XA # 其他Seata配置... // 服务实现类
@Service
public class OrderService { @Autowired private OrderMapper orderMapper; @GlobalTransactional public void createOrder(Order order) { // 执行订单创建逻辑 orderMapper.insert(order); // 调用其他服务或执行其他业务逻辑... }
} // Mapper接口
@Mapper
public interface OrderMapper { void insert(Order order); // 其他数据库操作方法...
} // 实体类
public class Order { private Long id; private String userId; private BigDecimal amount; // 其他字段和getter/setter方法...
}
在上面的代码中,@GlobalTransactional注解标记了全局事务的边界。当createOrder方法被调用时,Seata会启动一个全局事务,并协调所有参与的分支事务以保证数据的一致性。注意,这里假设数据库已经支持XA协议,并且已经正确配置了Seata Server和相关依赖。
四、总结
Seata作为开源的分布式事务中间件,在微服务架构下提供了高性能和简单易用的分布式事务服务。它支持AT、TCC、Saga和XA四种事务模式,每种模式各有优缺点和适用场景。AT模式通过自动生成事务的二阶段提交和回滚,简化了编程模型,但存在数据一致性风险和跨数据库事务支持有限的问题。TCC模式允许业务方细粒度控制事务的每个阶段,灵活性高且性能优越,但业务侵入性强且实现难度大。Saga模式适用于长事务,通过补偿操作保证事务正确性,但补偿操作复杂且存在数据一致性风险。XA模式则利用数据库对XA协议的支持,保证数据强一致性,但性能较差且存在单点问题。开发者在选择使用Seata时,应根据具体业务场景和需求,选择合适的事务模式,并合理配置和使用Seata以保证分布式事务的一致性和性能。
相关文章:
中间件之Seata
一、引言 在微服务架构日益盛行的今天,分布式事务成为了一个必须面对和解决的问题。传统的本地事务已经无法满足分布式环境下的数据一致性需求,因此分布式事务解决方案应运而生。Seata作为一款开源的分布式事务中间件,以其高性能、易用性和灵…...

MySQL 异常: “Host ‘xxx‘ is not allowed to connect to this MySQL server“
update user set host % where user root; FLUSH PRIVILEGES; 这两行代码就行...
c语言中字符串函数strlen,strcmp,strcpy,srtcat,strncpy,strncat,strncmp
1.strlen的使用和模拟实现 strlen 用来求字符串的长度,统计\0之前字符的个数。 模拟实现1:计数参数法 #include<stdio.h> #include<assert.h> size_t my_strlen(char* str) {int count0;assert(str);//assert断言是判断是字符串不能为空w…...
携程线下一面,面试内容:
面试时间:2024/9/12 • 实例方法和静态方法有什么不一样? • Java中的异常有哪几类?分别怎么使用? • 常用的集合类有哪些?比如List如何排序? • ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和各自适应的场景是什么? • 内存溢出是怎么…...

DeepL翻译:全世界最准确的翻译
DeepL翻译是一款高质量的机器翻译工具,以下从产品描述、产品特色、适用人群、适用场景四个方面对其进行介绍: 体验地址:DeepL翻译:全世界最准确的翻译 产品描述 DeepL是一家德国公司,以其高质量的机器翻译服务而闻名…...

15分钟学Go 实战项目一:命令行工具
实战项目一:命令行工具 1. 引言 命令行工具是开发者常用的工具之一,它可以帮助用户通过命令行界面对程序进行控制和交互。在这节中,我们将创建一个简单的命令行工具,以帮助你理解Go语言的基本语法和如何处理命令行输入。在这个过…...
lesson02 作业
lesson02-01作业 小红的体重是 m 千克,她想知道自己的体重在磅(1 千克约等于 2.20462 磅)是多少 输入描述 输入一个整数表示小红的标准体重m(kg) 输出描述 输出一个整数表示转换后的磅值n 磅 示例 输入: 50 输出:…...

港大和字节提出长视频生成模型Loong,可生成具有一致外观、大运动动态和自然场景过渡的分钟级长视频。
HKU, ByteDance|⭐️ 港大和字节联合提出长视频生成模型Loong,该模型可以生成外观一致、运动动态大、场景过渡自然的分钟级长视频。选择以统一的顺序对文本标记和视频标记进行建模,并使用渐进式短到长训练方案和损失重新加权来克服长视频训练…...

RabbitMQ进阶_可靠性
文章目录 一、 发送者的可靠性1.1、 生产者重试机制1.2、 生产者确认机制1.2.1、确认机制理论1.2.2、确认机制实现1.2.2.1、定义ReturnCallback1.2.2.2、定义ConfirmCallback 二、 MQ的可靠性2.1、 数据持久化2.1.1、 交换机持久化2.1.2、 队列持久化2.1.3、 消息持久化 2.2、 …...

JavaScript字符串的常用方法有哪些?
1.1操作方法 归纳为增删查改 1.1.1增 这里不是直接增添内容,而是创建字符串的一个副本,再进行操作 处理用以及${}进行字符串拼接外,还可以通过concat 1.1.1.1concat 用于将一个或多个字符串拼接为一个新字符串(浅拷贝&#…...

jmeter发送post请求
在jmeter中,有两种常用的请求方式,get和post.它们两者的区别在于get请求的参数一般是放在路径中,可以使用用户自定义变量和函数助手等方式进行参数化,而post请求的参数不能随url发送,而是作为请求体提交给服务器。而在…...

图文深入理解Oracle Total Recall
List item 题记:本文图文深入理解Oracle Total Recall技术。 1. Oracle Total Recall 概述 Oracle Total Recall(也称为 Flashback Data Archive - 闪回数据归档)提供了一种用于跟踪数据库更改的机制,可自动跟踪数据库历史更改…...

腾讯云控制台URL刷新URL预热 使用接口刷新
如图所示的俩个控制台功能,调用腾讯云的接口执行这俩个动作 (代码可以优化)nodejs框架是express, 这里粘贴调用成功的代码示例,做个记录。 app.get(/PurgeUrlsCache, async function (req, res, next) {// Depends on tencentclo…...

构建后端为etcd的CoreDNS的容器集群(二)、下载最新的etcd容器镜像
在尝试获取etcd的容器的最新版本镜像时,使用latest作为tag取到的并非最新版本,本文尝试用实际最新版本的版本号进行pull,从而取到想的最新版etcd容器镜像。 一、用latest作为tag尝试下载最新etcd的镜像 1、下载镜像 [rootlocalhost opt]# …...
libaom-all-intra参数说明
part_sf.less_rectangular_check_level 1; 这个设置可能控制编码器在分割画面时使用非矩形分区的检查级别。part_sf.ml_prune_partition 1; 这个设置可能用于基于机器学习(ML)的分区修剪,以减少不必要的计算。part_sf.prune_ext_partition_…...

应用假死?
有个客户10月18日应用接口都访问慢,nginx层面error显示连接拒绝,当时实施同学重启了java应用运行正常,但今天又卡死了,后台登录也登录不上去,看日志没异常,最终找到了数据库层面。 查看数据库相关日志&…...

SAP MM+FI - 物料管理模块与财务会计模块的集成配置
01 采购费用过账配置表 为了方便项目实施过程中采购费用过账配置,迪森资深专家根据丰富经验总结得出采购费用过账配置表,以供大家参考: 02 材料采购订单入库及结算 2.1采购订单入库 假设:入库数量1000PC,价格 10 元…...

初阶数据结构【3】--单链表(比顺序表还好的一种数据结构!!!)
本章概述 前情回顾单链表实现单链表彩蛋时刻!!! 前情回顾 咱们在上一章博客点击:《顺序表》的末尾,提出了一个问题,讲出了顺序表的缺点——有点浪费空间。所以,为了解决这个问题,我…...
mysql迁移到达梦的修改点
字段是达梦关键字的,达梦会给转成大写,如果不要转则需要使用双引号引起来。关键字参考:D:\dmdbms\doc\DM8_SQL语言使用手册.pdf 例如:RowCount Level Content Password Locked 中文乱码问题,需要在应用程序所在服务器的…...

Go小技巧易错点100例(十八)
正文: 使用下划线增加数字可读性 有时候我们代码里会定义很长的数字,虽然计算机程序能支持很大的数据的计算,但是对我们来说,可读性是一个需要考虑的点,特别是1后面全是0的时候。 但是这个问题在Go语言中是可以通过…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...