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//全局事务控制
相关推荐
Q8762239652 小时前
基于S7 - 200 PLC和组态王的大小球颜色大小材质分拣系统探索
分布式
小满、3 小时前
RabbitMQ:Fanout、Direct、Topic 交换机、队列声明与消息转换器
java·分布式·消息队列·rabbitmq·spring amqp
Wang's Blog3 小时前
RabbitMQ: 分布式事务的最终一致性解决方案
分布式·rabbitmq
RemainderTime3 小时前
(十)Spring Cloud Alibaba 2023.x:生产级 CI/CD 全链路实战(从 Dockerfile 到 Jenkins)
运维·spring cloud·ci/cd·docker·jenkins
低调电报4 小时前
我的第一个开源项目:鸿蒙分布式“口袋健身”教练
分布式·开源·harmonyos
2501_940198694 小时前
【前瞻创想】Kurator分布式云原生平台:从架构解析到企业级多云集群管理实战指南
分布式·云原生·架构
川214 小时前
Nacos和ZooKeeper的选型
分布式·zookeeper·云原生
醉舞经阁半卷书14 小时前
zookeeper服务端配置
网络·分布式·zookeeper
周杰伦_Jay5 小时前
【探索实战】从0到1精通Kurator:分布式云原生平台实战教程
分布式·云原生·kurator