《springcloud alibaba》 四 seata安装以及使用

news2024/11/27 19:39:16

目录

  • 准备
  • 调整db配置
    • 准备创建数据库
  • seata配置nacos
    • 配置confi.txt
    • 下载向nacos推送配置的脚本
  • 启动seata
  • 新建项目
  • order-seata项目 订单项目
    • 数据库脚本
    • pom.xml
    • application.yml
    • 启动类
    • 实体类
    • dao类
    • service类
    • controller类
    • feign类
    • mapper类
  • stock-seata 库存项目
    • 数据库脚本
    • pom.xml
    • application.yml
    • 启动类
    • 实体类
    • dao类
    • service类
    • controller类
    • mapper类
  • 测试
  • 特殊情况
  • 分布式事务
    • order-seata项目变动
      • pom.xml
      • application.yml
      • controller
    • stock-seata项目变动
      • pom.xml
      • application.yml
    • 脚本
    • 效果
  • 分布式事务原理
    • nacos配置问题
    • seata的几个表都是什么情况

准备

名称版本
Nacos1.4.5
seata1.4.0
alibabacloud2.2.5.RELEASE
  • 本博客版本

seata官网地址
seata安装包下载
在这里插入图片描述

  • 没有linux服务器,可本地搭建玩一下
  • 注意alibaba版本跟seata版本一定要严格控制,不然会出现一些奇奇怪怪的问题

默认数据存储分为2钟,一种是存在bin目录下的root.data文件里面,还有一种是db方式,本文使用db模式

调整db配置

  • 注意mysql数据库的版本得5.7以上。-
  • 修改配置文件之前,别慌,先copy一遍再说,养成好习惯
    在这里插入图片描述
  • 调整模式为db, 修改db对应的配置

准备创建数据库

在这里插入图片描述
mysql脚本下载地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 先把整个项目下载,然后到这个目录下,找到mysql.sql

seata配置nacos

在这里插入图片描述

  • 先备份一下配置文件
    在这里插入图片描述
  • 删除其他没有用的配置,调整一下配置

配置confi.txt

到之前下载好的依赖包中copy对应的config.txt文件,放到seata目录下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 修改存储类型
    在这里插入图片描述
  • 调整为自己对应的url地址,以及账号和密码

下载向nacos推送配置的脚本

在这里插入图片描述

  • 将该脚本移动到seata的conf配置下
    在这里插入图片描述
sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t seata -u nacos -w nacos
# h: nacos服务ip.
# p: nacos服务端口号.
# g: 想要的分组信息.
# t: 第一步新建的命名空间.
# u: nacos登录名.
# w: nacos登录密码

如果是本地没有做任务的修改,直接运行就行
在这里插入图片描述

  • 大概运行5分钟左右
    在这里插入图片描述
  • 很奇葩的设计,搞不懂为什么不单独弄一个文件来存储所有的内容,而是key value的方式,看起来很乱,建议单独创建一个seata的命令空间用来存储这些配置

启动seata

在这里插入图片描述
在这里插入图片描述

  • window启动用bat文件
    在这里插入图片描述
  • 可以看出默认端口为8091,也可以自定义
    在这里插入图片描述
  • 在服务列表中,就可以看到多了一个seata-server的服务
  • 因为window版本,不好演示集群方式,所以我这里的集群数量是1

新建项目

在这里插入图片描述
在之前的基础上新增一个seata项目
在这里插入图片描述

  • 注意,新增后,该项目是没有蓝点的
    在这里插入图片描述

  • 添加+号,解决蓝点问题
    在这里插入图片描述

  • 自己手动补一下seata这个目录

  • 创建模块order-seata和stock-seata

order-seata项目 订单项目

在这里插入图片描述

  • 新增这两个项目

在这里插入图片描述

  • 库存项目的结构

数据库脚本

create database seata_order;
use seata_order;
 
CREATE TABLE `order_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` varchar(200) DEFAULT NULL,
  `total_amount` decimal(10,3) DEFAULT NULL,
  `statu` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
  • 新增数据库

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lcs.springcloud</groupId>
        <artifactId>springcloudalibaba</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>order-nacos</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>order</finalName>
    </build>
</project>

application.yml

server:
  port: 8190


spring:
  application:
    name: order-seata

  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: localhost:8848
        username: nacos
        password: nacos


  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.10.108:3306/seata_order?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useCursorFetch=true
      username: root
      password: 12312312
mybatis:
  mapper-locations: classpath:mapper/*.xml

启动类

package com.lcs.springcloud;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@MapperScan("com.lcs.springcloud.dao")
@EnableFeignClients
public class OrderSeataApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderSeataApplication.class);
    }
}

实体类

package com.lcs.springcloud.entity;

import java.math.BigDecimal;

public class OrderTbl {

    private Integer id;
    private String product_id;
    private BigDecimal total_amount;
    private Integer statu;

    public OrderTbl() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProduct_id() {
        return product_id;
    }

    public void setProduct_id(String product_id) {
        this.product_id = product_id;
    }

    public BigDecimal getTotal_amount() {
        return total_amount;
    }

    public void setTotal_amount(BigDecimal total_amount) {
        this.total_amount = total_amount;
    }

    public Integer getStatu() {
        return statu;
    }

    public void setStatu(Integer statu) {
        this.statu = statu;
    }

    @Override
    public String toString() {
        return "OrderTbl{" +
                "id=" + id +
                ", product_id='" + product_id + '\'' +
                ", total_amount=" + total_amount +
                ", statu=" + statu +
                '}';
    }
}

dao类

package com.lcs.springcloud.dao;

import com.lcs.springcloud.entity.OrderTbl;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderDao {

    void insert(OrderTbl orderTbl);
}

service类

package com.lcs.springcloud.service;

import com.lcs.springcloud.dao.OrderDao;
import com.lcs.springcloud.entity.OrderTbl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    @Autowired
    OrderDao orderDao;

    public void insert(OrderTbl orderTbl) {
        orderDao.insert(orderTbl);
    }
}

controller类

package com.lcs.springcloud.controller;

import com.lcs.springcloud.entity.OrderTbl;
import com.lcs.springcloud.feign.StockOpenFeign;
import com.lcs.springcloud.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @Autowired
    StockOpenFeign stockOpenFeign;

    @RequestMapping("/add")
    public String add(){

        OrderTbl orderTbl = new OrderTbl();
        orderTbl.setProduct_id("10");
        orderTbl.setTotal_amount(new BigDecimal(3000));
        orderTbl.setStatu(0);
        orderService.insert(orderTbl);

        String reduct = stockOpenFeign.reduct(orderTbl.getProduct_id());
        return "add order "+reduct;
    }
}

feign类

package com.lcs.springcloud.controller;

import com.lcs.springcloud.entity.OrderTbl;
import com.lcs.springcloud.feign.StockOpenFeign;
import com.lcs.springcloud.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @Autowired
    StockOpenFeign stockOpenFeign;

    @RequestMapping("/add")
    public String add(){

        OrderTbl orderTbl = new OrderTbl();
        orderTbl.setProduct_id("10");
        orderTbl.setTotal_amount(new BigDecimal(3000));
        orderTbl.setStatu(0);
        orderService.insert(orderTbl);

        String reduct = stockOpenFeign.reduct(orderTbl.getProduct_id());
        return "add order "+reduct;
    }
}

mapper类

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lcs.springcloud.dao.OrderDao">

    <!-- 主键自增长的插入 -->
    <insert id="insert" parameterType="com.lcs.springcloud.entity.OrderTbl" useGeneratedKeys="true" keyProperty="id">
        insert into order_tbl(product_id,total_amount,statu) values(
                                                                                   #{product_id},
                                                                                   #{total_amount},
                                                                                   #{statu}
                                                                               );
    </insert>
</mapper>

stock-seata 库存项目

在这里插入图片描述

数据库脚本

 create database seata_stock;
use seata_stock;
 
CREATE TABLE `stock_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` varchar(200) DEFAULT NULL,
  `count` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

INSERT INTO `seata_stock`.`stock_tbl` (`id`, `product_id`, `count`) VALUES (1, '10', 100);

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lcs.springcloud</groupId>
        <artifactId>springcloudalibaba</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>stock-seata</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <!-- Nacos服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--继承了父项目,不需要添加版本号-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.3.5.RELEASE</version>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
            <!-- 排除冲突的jar包文件-->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-jdbc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--Mysql驱动器-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
            <scope>runtime</scope>
        </dependency>

        <!-- druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>order-seata</finalName>
    </build>
</project>

application.yml

server:
  port: 8200


spring:
  application:
    name: stock-seata

  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: localhost:8848
        username: nacos
        password: nacos

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      #url: jdbc:mysql://10.153.96.31:3306/iomm-collection?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useCursorFetch=true
      url: jdbc:mysql://112.74.51.171:3306/seata_stock?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useCursorFetch=true
      username: root
      password: Zy_746498
mybatis:
  mapper-locations: classpath:mapper/*.xml

启动类

package com.lcs.springcloud;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.lcs.springcloud.dao")
public class StockSeataApplication {
    public static void main(String[] args) {
        SpringApplication.run(StockSeataApplication.class,args);
    }
}

实体类

package com.lcs.springcloud.entity;

public class StockTbl {

    private Integer id;
    private String product_id;
    private Integer count;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProduct_id() {
        return product_id;
    }

    public void setProduct_id(String product_id) {
        this.product_id = product_id;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }
}

dao类

package com.lcs.springcloud.dao;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface StockDao {

    void updateStock(@Param("product_id")String product_id);
}

service类

package com.lcs.springcloud.service;

import com.lcs.springcloud.dao.StockDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StockService {
     @Autowired
     StockDao stockDao;

    public String updateStock(String product_id) {
        try {
            stockDao.updateStock(product_id);
            return "扣减库存成功";
        }catch (Exception e){
            return "更新库存失败";
        }
    }
}

controller类

package com.lcs.springcloud.controller;

import com.lcs.springcloud.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/stock")
public class StockController {

    @Autowired
    StockService stockService;

    @Value("${server.port}")
    String port;

    @RequestMapping("/reduct")
    public String reduct(@RequestParam(value = "product_id") String product_id){
        return stockService.updateStock(product_id);
    }

}

mapper类

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lcs.springcloud.dao.StockDao">

    <!-- 主键自增长的插入 -->
    <update id="updateStock"  parameterType="java.lang.String" >
        update stock_tbl  SET count= count-1 where product_id=#{product_id}
    </update>
</mapper>

测试

前提: 保持已经开启nacos,不知道的可以先学习一下nacos
在这里插入图片描述

  • 订单表 默认为空
    在这里插入图片描述
  • 库存表默认为100个库存

运行http://localhost:8190/order/add
在这里插入图片描述
结果如下:
在这里插入图片描述

在这里插入图片描述

  • 订单表新增一条记录,库存表-1,说明项目搭建成功

特殊情况

已知: order和stock是两个库
把order的controller代码,改一下

package com.lcs.springcloud.controller;

import com.lcs.springcloud.entity.OrderTbl;
import com.lcs.springcloud.feign.StockOpenFeign;
import com.lcs.springcloud.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @Autowired
    StockOpenFeign stockOpenFeign;

    @RequestMapping("/add")
    @Transactional
    public String add(){

        OrderTbl orderTbl = new OrderTbl();
        orderTbl.setProduct_id("10");
        orderTbl.setTotal_amount(new BigDecimal(3000));
        orderTbl.setStatu(0);

        //1. 插入订单
        orderService.insert(orderTbl);

        //2. 扣减库存
        String reduct = stockOpenFeign.reduct(orderTbl.getProduct_id());

        // 3. 出现问题
         int a= 1/0;
        return "add order "+reduct;
    }
}

在这里插入图片描述

  • 都知道0不能作为分母,必报错, 大家说一下这个接口是多少?
    订单插入进行了回滚,库存表进行扣减库存,为什么?
    这是因为@transaction事物是不支持跨库回滚的。

分布式事务

代码版本在上续上面做改动,请保证上面能先运行后, 再看该步骤

order-seata项目变动

pom.xml

 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
  • 为什么加了一个cglib的包?
    在这里插入图片描述
  • 报cg相关的一个错,猜测估计是依赖冲突的问题,查了一下项目依赖,发现只有可能cglib的问题
    在这里插入图片描述

application.yml

server:
  port: 8190


spring:
  application:
    name: order-seata

  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: localhost:8848
        username: nacos
        password: nacos
    alibaba:
      seata:
        tx-service-group: default_tx_group


  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata_order?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useCursorFetch=true
      username: root
      password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml

seata:
  registry:
    #配置seata的注册中心
    type: nacos
    nacos:
      ### nacos服务器地址
      server-addr: localhost:8848
      username: nacos
      password: nacos
      ### nacos服务名
      application: seata-server
  config:
    type: nacos
    nacos:
      ### nacos服务器地址
      server-addr: localhost:8848
      username: nacos
      password: nacos
      group: SEATA_GROUP

在这里插入图片描述

  • 为什么叫这个名字,看自己seata-server的配置
    在这里插入图片描述
    在这里插入图片描述
  • 这里标红的,就是我们需要填写的名字,在网上可以查到很多叫guangzhou的,这是因为别人重命名咯

controller

在这里插入图片描述

  • 注解改为@GlobalTransactional,表示是分布式事务

stock-seata项目变动

pom.xml

 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

application.yml

server:
  port: 8200


spring:
  application:
    name: stock-seata

  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: localhost:8848
        username: nacos
        password: nacos
    alibaba:
      seata:
        tx-service-group: default_tx_group

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata_stock?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useCursorFetch=true
      username: root
      password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml

seata:
  registry:
    #配置seata的注册中心
    type: nacos
    nacos:
      ### nacos服务器地址
      server-addr: localhost:8848
      username: nacos
      password: nacos
      ### nacos服务名
      application: seata-server
  config:
    type: nacos
    nacos:
      ### nacos服务器地址
      server-addr: localhost:8848
      username: nacos
      password: nacos
      group: SEATA_GROUP

  • 跟order项目类似,就是client跟seata以及nacos进行通信

脚本

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=3 DEFAULT CHARSET=utf8;

在这里插入图片描述

  • 涉及到分布式事务的库,都需要新增该undo-log得表,他会记录修改前,以及修改后的sql,以便逆向回滚
  • 例如你执行了新增,逆向就是删除

效果

在这里插入图片描述

  • order表
    在这里插入图片描述
  • 库存表

在这里插入图片描述
执行http://localhost:8190/order/add,查看数据库,出现异常后

  • 之前使用@transation是,订单回滚,库存减咯
  • 选择使用@globaTransation注解,订单回滚,库存不变

分布式事务原理

nacos配置问题

在这里插入图片描述
启动后,在bin下面多了一个store开头的文件夹,why?
我不是改成db模式吗?为什么配置没有生效,查了半天,才发现nacos的配置,竟然是默认的
在这里插入图片描述

  • 搜索store.mode*改成db

启动项目后,竟然报数据库的一个错误,怎么可能,我数据库的配置,都是copy的项目里面,不可能出问题,那原因只有一个,就是nacos里面的初始化配置又有问题
在这里插入图片描述

  • 修改nacos这三个的配置,再启动项目,seata得bin下面,没有文件夹生成,说明切换成db模式成功

seata的几个表都是什么情况

在这里插入图片描述

  • seata的表

在这里插入图片描述

  • 这是seata的一个流程图
    在这里插入图片描述
  • 输入http://localhost:8190/order/add,在进入方法的时候打入断点
    在这里插入图片描述
    在这里插入图片描述
  • global_table表生成了一个xid 拼接方式是ip+端口再加一个唯一id
  • xid 全局事务id
  • application_id 应用id
  • transaction_service_group 分组
  • transaction_name 事物加在那个方法上面(以前有个版本会标注在具体类具体方法),新版本后,变动了,好奇他底层是什么映射的,知道的,可以下方交流一下
    在这里插入图片描述
  • 断点执行到这里
    在这里插入图片描述
  • branch_table 表新增了一条数据,这个是分支Xid
    在这里插入图片描述
  • 订单库的undo-log,也新增了一条数据
    在这里插入图片描述
  • lock_table表变化会存储锁表的信息
  • pk就是主键的id
#到order库调用该sql,查看blob存放的内容
select CONVERT(t.rollback_info USING utf8) from undo_log t

  • 如下图
    在这里插入图片描述
  • 因为是插入语句,所以beforeImage之前是没有数据的,afterImage存放的就是修改后的数据

断点走完后,所有的seata表数据都会回滚,如果遇到异常退出的情况,请先清空表数据

代码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1578044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高效解决Ubuntu Server 18.04.1 LTS 64bit更新gdb8.1.1到gdb12.1

文章目录 问题解决步骤 问题 因为需要用到gdb一些指令&#xff0c;但是gdb8.x好像存在普遍的问题&#xff0c;实现不了某些指令&#xff0c;比方说set detach-on-fork on&#xff0c;升级版本也没有比较好的教程 经过我不断的试错&#xff0c;我终于升级成功了&#xff01;&a…

Qt使用QWidget重绘实现圆环形渐变色进度条(支持不确定进度模式)

效果如下&#xff1a; 从纯竖直方向顶部蓝色到底部青色的渐变。 从左上角偏左45到右下角偏右45的蓝色到青色渐变。 从左上角偏左22.5到右下角偏右22.5的蓝色到青色渐变。&#xff08;这个角度渐变最好看&#xff09; 可以选择添加背景图片 支持两种模式&#xff1a;正常进度模…

【完全背包求方案数问题】AcWing1023.买书(赋练习题目)

【题目链接】活动 - AcWing 输入样例1&#xff1a; 20输出样例1&#xff1a; 2输入样例2&#xff1a; 15输出样例2&#xff1a; 0输入样例3&#xff1a; 0输出样例3&#xff1a; 1 【代码】 //1023.买书——完全背包问题#include<bits/stdc.h>using namespace st…

我去,PMP原来不是所有人都能报!

很多人可能觉得PMP的报名条件很复杂&#xff0c;又是经验要求&#xff0c;又是学历要求的&#xff0c;网络上关于PMP报名条件说的层出不穷&#xff0c;今天给大家统一一下&#xff0c;报名PMP究竟需要什么条件&#xff1a; 官方报考条件&#xff1a; 一、报名考生必须具备35小…

【I2C总线驱动】

一、I2C总线背景知识 SOC芯片平台的外设分为&#xff1a; 一级外设&#xff1a;外设控制器集成在SOC芯片内部二级外设&#xff1a;外设控制器由另一块芯片负责&#xff0c;通过一些通讯总线与SOC芯片相连 Inter-Integrated Circuit&#xff1a; 字面意思是用于“集成电路之间…

多叉树题目:子树中标签相同的结点数

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;子树中标签相同的结点数 出处&#xff1a;1519. 子树中标签相同的结点数 难度 5 级 题目描述 要求 给你一个树&#xff08;即一个连通的无向无环图…

QT 使用redis ,连接并使用

一.redis安装 链接&#xff1a;https://pan.baidu.com/s/17fXKOj5M4VIypR0y5_xtHw 提取码&#xff1a;1234 1.下载得到文件夹如图 course_redis为安装包。 2.启动Redis服务 把安装包解压到某个路径下即可。 打开cmd窗口&#xff0c;切换到Redis安装路径&#xff0c;输入 r…

飞企互联-FE企业运营管理平台 druid路径 弱口令漏洞复现

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外,支持企业B2B、C2B与O2O等核心需求,为不同行业客户的互联网+转型提供支持。 0x02 漏洞概述 飞企互联-FE企业…

AI编程005/ 逆向生成mysql的建表语句

1/ 通过insert into 语句生成建表语句 有些时候我们能获取到表的insert语句&#xff0c;但是没有表结构。我们可以借助AI工具&#xff0c;让其逆向生成mysql的建表语句。 提示词如下&#xff1a; 根据下面的SQL语句&#xff0c;逆向生存mysql的建表语句&#xff0c;每个字段…

所有网站都需要使用SSL证书?

SSL证书对于网站的重要性&#xff0c;简单来说就是&#xff1a; 保护隐私&#xff1a;就像给你的信封加了密码锁&#xff0c;SSL证书让网站和用户之间的所有交流都变得保密。当你在网站上输入密码、银行卡号等敏感信息时&#xff0c;有了SSL证书&#xff0c;这些信息就会被加密…

申请北京资产评估公司资产评估备案要什么条件

北京资产评估注册要求&#xff0c;很多人想办理资产评估公司&#xff0c;但是不知道怎么申请评估公司更快效率更高。我公司是专业办理资产评估公司的专业代理机构&#xff0c;能办理资产评估公司注册&#xff0c;资产评估公司人员代持&#xff0c;等一系列的服务&#xff0c;关…

谷歌DeepMind发布Gecko:专攻检索,与大7倍模型相抗衡

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 Gecko 是一种通用的文本嵌入模型&#xff0c;可用于训练包括文档检索、语义相似度和分类等各…

积木-蓝桥每日真题

0积木 - 蓝桥云课 (lanqiao.cn) 题目描述 小明用积木搭了一个城堡。 为了方便&#xff0c;小明在搭的时候用的是一样大小的正方体积木&#xff0c;搭在了一个n行m列的方格图上&#xff0c;每个积木正好占据方格图的一个小方格。 当然&#xff0c;小明的城堡并不是平面的&#x…

Docker 安装RabbitMQ以及使用客户端图形化界面

目录 一、点击进入docker 镜像仓库 1.1 直接在官网里 搜索 rabbitmq 1.2 在标签里 直接搜索3.10-management 因为这个标签包含用户操作界面 二、启动docker 2.1 首先拉取镜像&#xff1a; 2.2 Docker运行&#xff0c;并设置开机自启动 三、访问用户操作界面 一、点击进入…

算法练习第12天|● 239. 滑动窗口最大值● 347.前 K 个高频元素

239.滑动窗口的最大值 力扣原题 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff…

使用 Jenkins、Gitlab、Harbor、Helm、k8s 来实现流水线作业

文章目录 一、流程二、Dockerfile 使用 Jenkins、Gitlab、Harbor、Helm、Kubernetes 来实现一个完整的持续集成和持续部署的流水线作业 一、流程 开发人员提交代码到 Gitlab 代码仓库通过 Gitlab 配置的 Jenkins Webhook 触发 Pipeline 自动构建Jenkins 触发构建构建任务&…

C++设计模式:桥模式(五)

1、定义与动机 桥模式定义&#xff1a;将抽象部分&#xff08;业务功能&#xff09;与实现部分&#xff08;平台实现&#xff09;分离&#xff0c;使他们可以独立地变化引入动机&#xff1a; 由于某些类型的固有的实现逻辑&#xff0c;使得它们具有两个变化的维度&#xff0c;…

Jenkins 持续集成 【CICD】

持续集成 &#xff08;Continuous integration&#xff0c;简称CI&#xff09; 持续集成是一种开发实践&#xff0c;它倡导团队成员频繁的集成他们的工作&#xff0c;每次集成都通过自动化构建&#xff08;包括编译、构建、打包、部署、自动化测试&#xff09;来验证&#xff…

libVLC 提取视频帧

在前面的文章中&#xff0c;我们使用libvlc_media_player_set_hwnd设置了视频的显示的窗口。 libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui.widgetShow->winId()); 如果我们想要提取每一帧数据&#xff0c;将数据保存到本地&#xff0c;该如何操作呢&#x…

思迈特软件与上海德拓签署战略合作协议,携手赋能企业数字化转型

3月27日&#xff0c;广州思迈特软件有限公司&#xff08;简称“思迈特软件”&#xff09;与上海德拓信息技术有限公司&#xff08;简称“德拓信息”&#xff09;正式签约建立战略合作伙伴关系。双方将在数字化转型、数据服务、数据应用以及市场资源等多个领域展开深度合作&…