分布式事务以及Seata(XA、AT模式)

目录

一、分布式事务问题:

二、Seata:

TC部署:

微服务集成Seata:

分布式事务-XA模式:

分布式事务-AT模式:


一、分布式事务问题:

这张图我们可以看到微服务的一个运作,现在假设创建订单、清理购物车这两个步骤没有出现问题,而扣减库存接口报错;由于交易服务调用了库存服务中的方法,因此扣减库存时报错会通知到交易服务,创建订单的事务就会被回滚,也就是1、3回滚;但是购物车服务是被交易服务调用的,购物车服务与库存服务之间并没有直接关系,这就会导致购物车服务的清理购物车事务没有得到回滚而是直接提交;这就会导致数据的不一致性,从业务上看就是提交订单失败但是购物车被清理了;所以就需要引入全局事务来解决该问题

二、Seata:

其实分布式事务产生的一个重要原因,就是参与事务的多个分支事务互相无感知,不知道彼此的执行状态。因此解决分布式事务的思想非常简单:

就是找一个统一的事务协调者,与多个分支事务通信,检测每个分支事务的执行状态,保证全局事务下的每一个分支事务同时成功或失败即可。大多数的分布式事务框架都是基于这个理论来实现的。

Seata也不例外,在Seata的事务管理中有三个重要的角色:

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

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

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

其中,TMRM 可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TMRM 就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。

TC服务则是事务协调中心,是一个独立的微服务,需要单独部署。

那么我们就来部署一下TC服务:

TC部署:

1.Seata支持多种存储模式,但考虑到持久化的需要,我们一般选择基于数据库存储。执行课前资料提供的《seata-tc.sql》,导入数据库表:

2.将整个seata文件夹、以及seata的tar包拷贝到虚拟机的/root目录:

3.加载seata的tar包并创建镜像:

4.确保nacos、mysql都在hm-net网络中并在虚拟机的/root目录执行下面的命令:

通过以下指令查看是否在网络当中:

bash 复制代码
docker network ls #用于查看所有网络,这里应该要有hm-net
docker inspect mysql #可以查看mysql容器的网络状况,里面应该要有hm-net
docker inspect nacos #可以查看nacos容器的网络状况,里面应该要有hm-net

这里发现nacos的网络没配置好,我们输入以下指令:

bash 复制代码
docker network connect hm-net nacos

再次执行docker inspect nacos查看:

接下来就可以执行容器的创建指令了:

bash 复制代码
docker run --name seata \
-p 8099:8099 \
-p 7099:7099 \
-e SEATA_IP=192.168.150.101 \
-v ./seata:/seata-server/resources \
--privileged=true \
--network hm-net \
-d \
seataio/seata-server:1.5.2

到网页中访问192.168.150.101:7099试试:

微服务集成Seata:

由于购物车、商品、交易模块要用到Seata,所有我们现在改造这三个模块的代码:

1.引入依赖:

XML 复制代码
  <!--统一配置管理-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>
  <!--读取bootstrap文件-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-bootstrap</artifactId>
  </dependency>
  <!--seata-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
  </dependency>

2.在nacos上添加一个共享的seata配置,命名为shared-seata.yaml

TypeScript 复制代码
seata:
  registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
    type: nacos # 注册中心类型 nacos
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址
      namespace: "" # namespace,默认为空
      group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUP
      application: seata-server # seata服务名称
      username: nacos
      password: nacos
  tx-service-group: hmall # 事务组名称
  service:
    vgroup-mapping: # 事务组与tc集群的映射关系
      hmall: "default"

3.给三个模块添加或修改bootstrap.yaml

TypeScript 复制代码
spring:
  application:
    name: *****-service # 服务名称
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址
      config:
        file-extension: yaml # 文件后缀名
        shared-configs: # 共享配置
          - dataId: shared-jdbc.yaml # 共享mybatis配置
          - dataId: shared-log.yaml # 共享日志配置
          - dataId: shared-swagger.yaml # 共享日志配置
          - dataId: shared-seata.yaml # 共享seata配置

4.修改原先的application.yaml文件:

TypeScript 复制代码
server:
  port: ****
feign:
  okhttp:
    enabled: true # 开启OKHttp连接池支持
  sentinel:
    enabled: true # 开启Feign对Sentinel的整合
hm:
  swagger:
    title: **服务接口文档
    package: com.hmall.*****.controller
  db:
    database: hm-*****

分布式事务-XA模式:

接下来我们就来实现XA模式:

1.在配置文件中指定要采用的分布式事务模式。我们可以在Nacos中的共享shared-seata.yaml配置文件中设置:

2.在事务的起点方法上添加@GlobalTransactional注解,将来TM就会基于这个方法判断全局事务范围,初始化全局事务。

以及涉及到的两个方法上添加@Transactional注解

分布式事务-AT模式:

具体实现:

1.在遭遇分布式事务问题的模块下创建快照表存储快照信息:

2.到nacos当中修改shared-seata.yaml:

相关推荐
寒山李白4 小时前
关于Java项目构建/配置工具方式(Gradle-Groovy、Gradle-Kotlin、Maven)的区别于选择
java·kotlin·gradle·maven
无妄无望4 小时前
docker学习(4)容器的生命周期与资源控制
java·学习·docker
MC丶科5 小时前
【SpringBoot 快速上手实战系列】5 分钟用 Spring Boot 搭建一个用户管理系统(含前后端分离)!新手也能一次跑通!
java·vue.js·spring boot·后端
千码君20165 小时前
React Native:从react的解构看编程众多语言中的解构
java·javascript·python·react native·react.js·解包·解构
夜白宋6 小时前
【word多文档docx合并】
java·word
@yanyu6666 小时前
idea中配置tomcat
java·mysql·tomcat
2501_916766546 小时前
【项目部署】JavaWeb、MavenJavaWeb项目部署至 Tomcat 的实现方式
java·tomcat
RoboWizard6 小时前
扩容刚需 金士顿新款Canvas Plus存储卡
java·spring·缓存·电脑·金士顿
lang201509287 小时前
Spring Boot 入门:5分钟搭建Hello World
java·spring boot·后端