spring cloud alibaba - seata分布式事务记录

  • 一般在微服务开发中,一个接口中涉及多服务调用,涉及在不同数据库的数据修改时,为了保证数据一致性等,就需要引入分布式事务。
  • 单应用引入本地事务 @Transactional(rollbackFor = Throwable.class),就可以。
  • 而分布式事务可以用 spring cloud alibaba - seata框架实现,在部署好nacos、seata客户端后,在接口声明@GlobalTransactional,就可以实现。
Seata介绍:是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。为用户提供了 ATTCCSAGAXA 事务模式,为用户打造一站式的分布式解决方案。 

Seata官网文档

常见分布式事务解决方案:

  • seata阿里分布式事务框架
  • 消息队列,可靠消息-》文章
  • Saga
  • XA

事务模式介绍:

  • AT 模式:是一种无侵入分布式事务解决方案。
    – 1阶段: Seata会拦截业务sql,解析sql语义找到业务sql要更新的数据,在数据更新前,保存更新前快照before image;然后执行业务sql更新数据;在数据更新后,将其保持成 after images,更新后快照,生成行锁。
    – 2阶段:如果接口正常执行未出现异常,因为业务sql在一阶段已提交,接口正常执行后删除快照数据和行锁,完全数据清理; 接口执行出现异常时,就会回滚数据,先执行脏写校检,对比当前数据库业务数据,与after image,如果一致则可以还原业务数据,出现脏写则需要人工处理;无脏写时,则通过before image 生成逆向sql还原数据。
  • TCC 模式:侵入性较强,自己实现相关事务控制逻辑,在整个过程基本没有锁,性能更强。
    – 事务发起方在一阶段执行Try方式,在二阶段提交执行confirm,回滚执行cancel。

版本对应 –
1

下载对应版本运行体,以及运行配置以及表
如1.4.2 版本
基本配置https://github.com/seata/seata/tree/1.4.2
运行jar https://github.com/seata/seata/tags

1
1

前置环境:只需配置一次

  1. 修改 seata-server-1.4.2\conf ,file.conf,选择对应存储模式,默认file单机模式
    1
    这里记录高可用db模式,修改file.conf 文件,切换db模式,并修改数据链接信息。
    在这里插入图片描述
  1. 修改 register.conf ,配置nacos连接信息。(事务参与者,需要与 seata通信);确保nacos正常启动后,修改源码中script资源目录下,\config-center\config.txt 修改注册信息,配置存储模式,数据库连接信息,事务分组信息,之后运行注册脚本nacos-config.sh,将信息注册到nacos。
  • 导入资源目录中数据库信息,创建数据库seata;执行 script\server\db\mysql.sql 文件
  • 运行 seata-server.bat
    在这里插入图片描述
    在这里插入图片描述
    2
    2
    2
    2
    3
    集群启动:
    2
    在服务参与者对应库中,添加 undo_log 表; 保持执行前后的源数据,script\client\at\db\mysql.sql
    2
-- 对应服务添加 undo_log表
CREATE TABLE `undo_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `context` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime(0) NULL,
  `log_modified` datetime(0) NULL,
  PRIMARY KEY (`id`) USING BTREE
);

代码整合

父项目依赖:

<dependencyManagement>

        <dependencies>
            <!--spring boot 公共版本定义-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--spring cloud 公共版本定义 通过dependencies完成继承-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--spring cloud alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>

    </dependencyManagement>

服务端依赖:

<!-- 客户端调用-openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!-- seata -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

服务参与者yml配置:

spring:
  application:
    name: stock-service
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848 #nacos服务地址
        file-extension: yaml  #配置文件类型
#seata 配置
seata:
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      application: seata-server
      username: nacos
      password: nacos
      group: SEATA_GROUP
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      group: SEATA_GROUP
  tx-service-group: my_test_tx_group

接口处,或service中 @GlobalTransactional

	@GlobalTransactional
    @RequestMapping("/add")
    public String add(){
    
    
        Order order = new Order(9,20,0);
        orderMapper.insert(order);
        String reduct = stockService.reduct(9);
        int i=1/0;
        return "ok"+reduct;
    }

前置环境配置有点烦琐,但只需配置一次,后续执行声明注解就可以实现分布式事务。

  • TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器
    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

流程分析,AT模式总结:
1 TC会生成一个XID作为该全局事务的编号。XID,会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起。
2. 在进入接口方法时,生成一个XID;将事务参与者,注册为全局事务的一个事务分支。每一个事务都是通过全局事务的XID来进行隔离,有多个分布式事务 @GlobalTransactional 就会有多个XID。多个XID来串联起这些事务参与者。

global_table,存储全局事务信息。
1
branch_table 分支事务信息。存储事务参与者
lock_table 锁表信息,目的:分支事务之间的隔离
undo_log 回滚快照数据

猜你喜欢

转载自blog.csdn.net/hesqlplus730/article/details/125610857