当前位置: 代码迷 >> 综合 >> 分布式事务解决方案之Alibaba Seata
  详细解决方案

分布式事务解决方案之Alibaba Seata

热度:98   发布时间:2023-12-08 06:58:13.0

文章目录

  • 分布式事务
  • Seata简介
  • Seata分布式事务处理过程
  • 1. seata server的安装和配置
  • 2. seata client 配置
    • 建undo_log表
    • 依赖
    • yaml配置
  • 3. Nacos配置中心添加seata的配置
  • 开启分布式事务功能
  • Q&A
  • 参考

  • 本文使用的nacos版本1.4.2,seata版本1.4.2。seata从v1.4.2版本开始,已支持从一个Nacos dataId中获取所有配置信息,只需要额外添加一个dataId配置项,低版本的配置要多一点,所以建议还是使用本文的版本
  • 本文只包含seata的安装和配置,不包含具体业务代码

分布式事务

  • 一次业务操作需要跨多个数据源或需要跨多个微服务进行RPC,就需要引入分布式事务,保证不同节点之间的数据一致性。
  • 分布式事务的实现有很多种,最具有代表性的是由 Oracle Tuxedo 系统提出的 XA 分布式事务协议。它包含两阶段提交(2PC)和三阶段提交(3PC)两种实现
  • 其他的还有:
    • MQ 事务:利用消息中间件来异步完成事务的后一半更新,实现系统的最终一致性。这个方式避免了像 XA 协议那样的性能问题。
    • TCC 事务:是 Try、Commit、Cancel 三种指令的缩写,其逻辑模式类似于 XA 两阶段提交,但是实现方式是在代码层面来人为实现。

Seata简介

  • Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGAXA 事务模式,为用户打造一站式的分布式解决方案。
  • 核心概念:一个 ID + 三个组件
    • Transaction ID XID :全局唯一的事务ID
    • Transaction Coordinator(TC) :事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚
    • Transaction Manager? :控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议
    • Resource Manager(RM) :控制分支事务,负责分支注册,状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚
  • 传统 2PC 的问题在 Seata 中得到了解决,它通过对本地关系数据库的分支事务的协调来驱动完成全局事务,是工作在应用层的中间件。主要优点是性能较好,且不长时间占用连接资源,它以高效并且对业务 0 侵入的方式解决微服务场景下面临的分布式事务问题
  • Seata实现2PC与传统2PC的差别
    • 架构层次方面:传统 2PC 方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而 Seata 的 RM 是以 jar 包的形式作为中间件层部署在应用程序这一侧的
    • 两阶段提交方面:传统 2PC无论第二阶段的决议是 commit 还是 rollback ,事务性资源的锁都要保持到 Phase2 完成才释放。而 Seata 的做法是在 Phase1 就将本地事务提交,这样就可以省去 Phase2 持锁的时间,整体提高效率。
      在这里插入图片描述

Seata分布式事务处理过程

在这里插入图片描述

  1. TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID
  2. XID在微服务调用链路的上下文中传播
  3. RM向TC注册分支事务,将其纳入XID对应全局事务的管辖
  4. TM向TC发起针对XID的全局提交或回滚决议;
  5. TC调度XID下管辖的全部分支事务完成提交或回滚请求。

1. seata server的安装和配置

  • 去官网下载1.4.2版本,解压即可(解压后可以阅读一下readme文件,了解server、client、config-center的区别)
  • 修改conf目录下的file.conf、registry.conf文件,这个简单,参考这篇文章的相关内容,其他部分就不要看了
  • 还需要创建seata数据库,执行官网提供的sql脚本即可

2. seata client 配置

建undo_log表

  • 在涉及到分布式事务的业务数据库中创建一个undo_log表,只需执行官网提供的sql脚本
  • 注意每个相关数据库都要建这个表,不是只建一个

依赖

  • 对于依赖的说明,参考官网
<!--nacos-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--seata-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><!--<version>2.2.1.RELEASE</version>--> <!--没有父pom就在这里指定版本--><exclusions><!--seata 排除自带的seata-spring-boot-starter--><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.4.2</version>
</dependency>
  • 父pom中的spring cloud alibaba版本为2.2.1.RELEASE
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.1.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>

yaml配置

server:port: 2001spring:application:name: seata-order-servicecloud:nacos:discovery:server-addr: localhost:8848datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata_orderusername: rootpassword: root
feign:hystrix:enabled: false
seata:enabled: trueenable-auto-data-source-proxy: true #是否开启数据源自动代理,默认为truetx-service-group: default_tx_group  #对应seataServer.properties中的service.vgroupMapping.default_tx_group 集群分组registry:type: nacos   #注册中心类型:nacosnacos:application: seata-server      # seata-server注册在nacos中的服务名server-addr: 127.0.0.1:8848    # nacos的地址端口group : SEATA_GROUP            # seata-server在nacos的分组namespace: ""           # seata-server在nacos的命名空间ID,默认是public,可以不填username: nacos                # nacos账号password: nacos                # nacos密码config:type: nacosnacos:server-addr: 127.0.0.1:8848group: SEATA_GROUPnamespace: ""                 # seata-server的配置文件的命名空间IDdataId: seataServer.properties       # seata-server在nacos的配置dataIdusername: nacospassword: nacoslogging:level:io:seata: infomybatis:mapperLocations: classpath:mapper/*.xml

3. Nacos配置中心添加seata的配置

seata配置添加到nacos后,各个client端就只需从nacos获取配置了

  • 需要一个config.txt文件,如何获取,参考官方文档-Nacos 配置中心
  • 然后需要修改config.txt文件的内容,一般就改store.mode,相应mode的配置当然也要改了
  • 注意不需要再执行nacos-config.sh脚本,直接在nacos配置管理中新建一个配置文件,配置内容就是config.txt的内容,格式为properties,如下图:
  • 完成后,启动seata即可
    在这里插入图片描述

开启分布式事务功能

  • 需要进行事务的方法上添加@GlobalTransactional(name = “唯一即可”, rollbackFor = Exception.class)
  • 成功了吗?开不开心?

Q&A

  • 启动微服务时,如果遇到报错:can not get cluster name in registry config ‘XXX‘, please make sure registry config correct,可以重启nacos和Seata试一试

参考

  • 官网新手部署指南
  • SpringCloud-2.0-周阳(24. 分布式事务 - Seata)学习笔记
  • 分布式事务有这一篇就够了!
  相关解决方案