springcloud alibaba(十)分布式事务

文章目录

分布式事务介绍

分布式事务是指参与事务的各组件(包括参与者、事务服务器、资源服务器和事务管理器)分布在分布式系统的不同节点上。

简而言之,分布式事务是将一个复杂操作拆分为多个子操作,这些子操作分布在不同的服务器上且属于不同的应用系统。分布式事务的核心要求是确保这些子操作要么全部成功执行,要么全部回滚。

从本质上来看,分布式事务旨在维护跨数据库的数据一致性。

Seata介绍

Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 通过 AT(自动补偿)、TCC(Try-Confirm-Cancel)、SAGA 和 XA 模式支持多种分布式事务场景,适用于微服务架构下的数据一致性需求。

Seata 核心组件
  • TC(Transaction Coordinator):事务协调器,负责全局事务的提交或回滚。
  • TM(Transaction Manager):事务管理器,定义全局事务的边界并发起全局提交或回滚。
  • RM(Resource Manager):资源管理器,管理分支事务的资源,与 TC 交互以注册分支事务和报告状态。
Seata 事务模式

AT 模式(自动补偿): 通过解析 SQL 生成前后镜像,实现自动回滚。适用于大多数业务场景,对代码侵入性低。
TCC 模式(Try-Confirm-Cancel): 需要业务实现 Try、Confirm、Cancel 接口,适用于需要高一致性的场景(如资金交易)。
SAGA 模式: 长事务解决方案,通过状态机驱动异步调用,适用于业务流程复杂且耗时的场景。
XA 模式: 基于数据库 XA 协议的两阶段提交,适用于支持 XA 协议的数据库(如 MySQL、Oracle)。

Seata 工作流程
  1. TM 向 TC 发起全局事务,生成全局唯一 XID。
  2. XID 通过微服务调用传递到各分支事务。
  3. RM 向 TC 注册分支事务,并将其纳入全局事务管理。
  4. TC 根据全局事务状态决定提交或回滚所有分支事务。
seata的使用

seata下载地址

修改配置文件

进入conf目录, 找到registry.conf

powershell 复制代码
registry {
  type = "nacos"
  nacos {
    serverAddr = "localhost"
    namespace = "public"
    cluster = "default"
  }
}

config {
  type = "nacos"
  nacos {
    serverAddr = "localhost"
    namespace = "public"
	cluster = "default"
  }
}
支持多种方式,这里使用的nacos,其他的方式可以删除掉。

修改nacos-config.txt

service.vgroup_mapping.service-order=default

service.vgroup_mapping.service-product=default

service.vgroup_mapping.service-user=default

初始化seata到nacos的配置

在 config 目录, 执行如下命令:

cd conf

nacos-config.sh 127.0.0.1

注意: 运行命令前需要保证nacos在运行状态。

在nacos配置列表查看是否有seata的配置

看到如上图所示,说明seata初始化到nacos配置成功。

启动seata服务

执行 cd bin

seata-server.bat -p 9000 -m file

启动后在 Nacos 的服务列表下面可以看到一个名为 serverAddr 的服务。

使用seata实现事务控制

需要数据库中添加一张undo_log表.

Seata 中的 undo_log 表是AT 模式(Seata 核心事务模式)实现分布式事务回滚的核心依赖,其核心作用是记录事务执行过程中数据的修改前 / 后镜像,当分布式事务需要回滚时,通过该表的日志信息将数据恢复到事务执行前的状态,保证分布式事务的原子性。

两个阶段:

AT 模式是基于「两阶段提交」的无侵入式分布式事务方案,undo_log 是 AT 模式实现第二阶段回滚的关键:

第一阶段(业务执行):执行业务 SQL 时,Seata 会拦截 SQL,记录数据的「前镜像」(修改前数据)和「后镜像」(修改后数据),并将这些信息写入 undo_log 表,同时锁定相关数据行;

第二阶段(提交 / 回滚):

若事务全局提交:删除 undo_log 中该事务的日志,释放锁;

若事务全局回滚:根据 undo_log 中的镜像数据,生成反向 SQL(如 UPDATE/DELETE/INSERT 的逆向操作),将数据恢复到修改前状态,完成后删除 undo_log 日志。

undo_log表结构:

sql 复制代码
CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
项目中关于seata的配置

在需要进行分布式控制的微服务中进行下面几项配置:

  1. 添加 依赖:
xml 复制代码
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 数据源代理配置
    Seata 是通过代理数据源实现事务分支的,所以需要配置 io.seata.rm.datasource.DataSourceProxy 的
    Bean,且是 @Primary默认的数据源,否则事务不会回滚,无法实现分布式事务
java 复制代码
@Configuration
public class DataSourceProxyConfig {
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DruidDataSource druidDataSource() {
		return new DruidDataSource();
	}
	@Primary
	@Bean
	public DataSourceProxy dataSource(DruidDataSource druidDataSource) {
		return new DataSourceProxy(druidDataSource);
	}
}
  1. 在yml配置文件中添加配置
yaml 复制代码
spring:
  application:
    name: service-order
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        shared-dataids: all-service.yaml # 配置要引入的配置
        refreshable-dataids: all-service.yaml # 配置要实现动态配置刷新的配置
        namespace: public
        group: SEATA_GROUP
    alibaba:
      seata:
        tx-service-group: ${spring.application.name}
  profiles:
    active: dev
  1. 在resources下添加Seata的配置文件 registry.conf
bash 复制代码
registry {
  type = "nacos"
  nacos {
    serverAddr = "localhost"
    namespace = "public"
    cluster = "default"
  }
}

config {
  type = "nacos"
  nacos {
    serverAddr = "localhost"
    namespace = "public"
	cluster = "default"
  }
}
  1. 在 调用方法上开启全局事务控制
    添加全局事务注解 @GlobalTransactional//全局事务控制
相关推荐
心中有国也有家1 天前
hccl 架构拆解:昇腾集合通信库到底在做什么?
人工智能·经验分享·笔记·分布式·算法·架构
188105069631 天前
摸鱼事务所——团队作业——大模型评测作业
大数据·hadoop·分布式
大连赵哥1 天前
分布式文件存储系统:Hadoop HDFS
hadoop·分布式·hdfs
玖笙&1 天前
✨WPF编程基础【3.3】:容器控件(附源码)
c++·wpf·visual studio
不爱编程的小陈2 天前
从存储引擎到文件系统:用FUSE将分布式KV挂载为本地目录
分布式
song5012 天前
对话:模型推理慢,怎么调
人工智能·分布式·深度学习·transformer·交互
LB21122 天前
消灭并发重复调用:基于 Agent 调用 LLM 的分布式 Single-Flight 实战
java·开发语言·redis·分布式·agent
心中有国也有家2 天前
ascend-boost-comm:一次写完,到处复用——算子公共平台的 M×N 哲学
人工智能·经验分享·笔记·分布式·算法
努力发光的程序员2 天前
互联网大厂Java面试故事:Spring Boot与微服务全栈技术实战问答
java·spring boot·spring cloud·微服务·kafka·hibernate·面试技巧
jameslogo2 天前
RocketMQ与Kafka零拷贝机制
分布式·kafka·rocketmq