Spring cloud 整合 Seata(At)

Nacos 整合 Seata (At) 模式

  Seata官网:https://seata.io/zh-cn/index.html

  代码:https://gitee.com/yihong-sword/learn-nacos-cloud.git

下载:

  1. Seata 服务端 (官网-下载-选择版本-选择binary)
  2. Seata 源码 (官网-下载-选择版本-选择source)

Seata 命令(Mac):

  1. 启动:./seata-server.sh

建表

  • Server 服务端 (这里创建表结构是需要创建一个新的数据库 比如 seata 后续是需要指定该数据库地址)
    • 在已经下好的源码里包含了 server 服务端所需要的表结构,路径为:seata/源码/seata-1.4.2/script/server/db 选择不同数据库.sql 执行即可
  • Client 业务端 (也就是代码里实际需要分布式事务的业务库)
    • 在已经下好的源码里包含了 server 业务端所需要的表结构,路径为:seata/源码/seata-1.4.2/script/client/at/db 选择不同数据库.sql 执行即可 (需要注意的是:如果一共有3个服务,那么就要在各自的业务库中分别创建该表)

修改server配置(Nacos)

  在已经下好源码里,是可以找到这些配置的模板,路径为:seata/源码/seata-1.4.2/script/server/config

file.conf

## transaction log store, only used in seata-server
store {
  ## store mode: file、db、redis
  mode = "file"

  ## file store property
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }

  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"
    ## 我看网上有修改这个的,我没有修改。但是也好用
    url = "jdbc:mysql://127.0.0.1:3306/seata"
    user = "mysql"
    password = "mysql"
    minConn = 5
    maxConn = 100
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }

  ## redis store property
  redis {
    host = "127.0.0.1"
    port = "6379"
    password = ""
    database = "0"
    minConn = 1
    maxConn = 10
    queryLimit = 100
  }

}

 

registry.conf

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos" 
  }
}

 

application.yml

源码路径为:seata/源码/seata-1.4.2/script/client/spring

事务分组专题(tx-service-group):https://seata.io/zh-cn/docs/user/transaction-group.html

下面代码需要复制到各项目application.yml文件内

seata:
  enabled: true
  application-id: provider
  tx-service-group: my_test_tx_group
  config:
    type: nacos
    nacos:
      namespace: ""
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      username: ""
      password: ""
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group : SEATA_GROUP
      namespace: ""
      username: ""
      password: ""
  log:
    exception-rate: 100

 

Nacos 配置中心

源码里路径为:seata/源码/seata-1.4.2/script/config-center/config.txt

修改完下面配置之后,保存原文件,返回上一层并进入nacos文件夹,执行./nacos-config.sh,此时配置已上传nacos

service.vgroupMapping.my_test_tx_group=default
service.disableGlobalTransaction=false
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
// 下面的驱动是mysql8.0版本 store.db.driverClassName=com.mysql.cj.jdbc.Driver
// 指定的seata 服务端创建的数据库 store.db.url=jdbc:mysql://127.0.0.1:3306/seata_server?useUnicode=true
&rewriteBatchedStatements=trueseata?useUnicode=true&rewriteBatchedStatements=true store.db.user=user store.db.password=password store.db.minConn=5 store.db.maxConn=30 store.db.globalTable=global_table store.db.branchTable=branch_table store.db.queryLimit=100 store.db.lockTable=lock_table store.db.maxWait=5000

 

项目配置(业务代码,我就不多写了,首先AT模式本就对业务代码侵入较少)

  • Jdk 14
  • Mysql 8.0
  • Nacos
  • Spring boot 2.4.10
  • Seata 2021.1
  • io.seata 1.3.0
  • Jpa 2.5
  • openFeign 3.0.2

Pom

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>learn_nacos_cloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>provider</module>
        <module>consumer</module>
        <module>consumer</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.4.10</spring-boot.version>
        <spring-cloud.version>2020.0.2</spring-cloud.version>
        <spring-cloud-alibaba.version>2020.0.RC1</spring-cloud-alibaba.version>
        <alibaba.seata.starter.version>2.2.5.RELEASE</alibaba.seata.starter.version>
        <lombok.version>1.18.20</lombok.version>
        <slf4j.version>1.7.25</slf4j.version>
        <jpa.version>2.5.0</jpa.version>
        <mysql.version>8.0.13</mysql.version>
        <spring-cloud-starter-openfeign.version>3.0.2</spring-cloud-starter-openfeign.version>
        <seata-spring-boot-starter.version>1.4.2</seata-spring-boot-starter.version>
        <nacos.cloud.starter.version>2.2.6.RC1</nacos.cloud.starter.version>
        <spring-cloud-starter-loadbalancer.version>3.0.4</spring-cloud-starter-loadbalancer.version>
    </properties>

    <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 依赖 -->
            <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>
            <!--nacos 注册中心服务发现-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>${nacos.cloud.starter.version}</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
                <version>${jpa.version}</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
                <version>LATEST</version>
                <exclusions>
                    <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.3.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>${spring-cloud-starter-openfeign.version}</version>
                <scope>compile</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-loadbalancer</artifactId>
                <version>${spring-cloud-starter-loadbalancer.version}</version>
            </dependency>
            <!-- hystrix-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
                <version>2.2.8.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

 

子项目 pom

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>learn_nacos_cloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <name>provider</name>
    <groupId>org.example</groupId>
    <artifactId>provider</artifactId>
    <version>${parent.version}</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </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-seata</artifactId>
        </dependency>

        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>14</maven.compiler.source>
        <maven.compiler.target>14</maven.compiler.target>
    </properties>

</project>

 

 

项目目录:

 

Seata At模式理解

官方讲解(完全可以轻易看懂):https://seata.io/zh-cn/docs/overview/what-is-seata.html

首先Seata 术语

  • TC (Transaction Coordinator) - 事务协调者

    维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器

    定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器

    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

 

工作原理简单说就是:在服务代码获取本地锁之后,在业务库undo_log 会生成一条记录,列:rollback_info 储存是一个json,保存的是该sql 执行前 以及执行后,

  • 事务回滚,会分析执行前是什么样的数据 ,并且拼装好sql执行,并且删除该记录
  • 正常执行,则直接删除掉该记录

 

异常及解决办法

  • Seata 和 OpenFeign 冲突  Error creating bean with name 'seataFeignObjectWrapper' defined in class path resource 这个错误就是版本不兼容。换成文档里的版本就不会有这个错了(我调试这个错误接近2个礼拜。。看了无数帖子 挨个试。。)
  • A component required a bean of type 'org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient' that could not be found. 这个比较有意思它的意思是缺失,但是由于之前我引用了 loadbalancer jar 也看过确实引入该class 所以就很迷惑,把该jar 引用给去掉就完事了。这个错就消失了

 

启动顺序

  1. Nacos
  2. Seata
  3. 项目

 

posted @ 2021-10-16 18:50  一只奋斗的猪  阅读(513)  评论(0编辑  收藏  举报