Seata1.2.0配置及分布式事务失效解决

2023-10-26

配置

版本说明:
springCloud Alibaba组件版本关系

我用的是 cloud Alibaba 2.2.1.RELEASE 、springboot 2.2.5.RELEASE、nacos 1.2.1、seata1.2.0

1. 配置数据库

seata 主要的任务便是对数据库进行事务回滚,保证事务的一致性,所以我们需要先行配置数据库,seata需要一个进行事务管理的数据库用于自身使用。
MySQL中创建 seata 数据库,存储引擎为 InnoDB(默认)

-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `global_table` (
  `xid` varchar(128)  not null,
  `transaction_id` bigint,
  `status` tinyint not null,
  `application_id` varchar(32),
  `transaction_service_group` varchar(32),
  `transaction_name` varchar(128),
  `timeout` int,
  `begin_time` bigint,
  `application_data` varchar(2000),
  `gmt_create` datetime,
  `gmt_modified` datetime,
  primary key (`xid`),
  key `idx_gmt_modified_status` (`gmt_modified`, `status`),
  key `idx_transaction_id` (`transaction_id`)
);

-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (
  `branch_id` bigint not null,
  `xid` varchar(128) not null,
  `transaction_id` bigint ,
  `resource_group_id` varchar(32),
  `resource_id` varchar(256) ,
  `lock_key` varchar(128) ,
  `branch_type` varchar(8) ,
  `status` tinyint,
  `client_id` varchar(64),
  `application_data` varchar(2000),
  `gmt_create` datetime,
  `gmt_modified` datetime,
  primary key (`branch_id`),
  key `idx_xid` (`xid`)
);

-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (
  `row_key` varchar(128) not null,
  `xid` varchar(96),
  `transaction_id` long ,
  `branch_id` long,
  `resource_id` varchar(256) ,
  `table_name` varchar(32) ,
  `pk` varchar(36) ,
  `gmt_create` datetime ,
  `gmt_modified` datetime,
  primary key(`row_key`)
);

在这里插入图片描述

2. 在涉及到的其它业务库中添加日志表 undo_log

该表用于事务回滚时,数据的恢复

-- the table to store seata xid data
-- 0.7.0+ add context
-- you must to init this sql for you business databese. the seata server not need it.
-- 此脚本必须初始化在你当前的业务数据库中,用于AT 模式XID记录。与server端无关(注:业务数据库)
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
drop table `undo_log`;
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=1 DEFAULT CHARSET=utf8;

在这里插入图片描述

3. 修改配置文件

在这里插入图片描述

3.1 file.conf


## seata-service
service {
  #交易服务组映射 的组名称必须要与客户端一致 my_test_tx_group  fsp_test_group必须要与registrt.conf 一致
  #transaction service group mapping
  vgroupMapping.my_test_tx_group = "fsp_test_group"
  #only support when registry.type=file, please don't set multiple addresses
  #这里设置ip, 一般不用改
  default.grouplist = "127.0.0.1:8091"
  #disable seata
  disableGlobalTransaction = false
}


## transaction log store, only used in seata-server
store {
  ## store mode: file、db
  ##TODO 修改为数据库类型
  mode = "db"

  ## 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
  #TODO 下面这一堆就安装自己MySQL去改就行了,使用的库便是我们上面创建的seata库
 db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) 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?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC"
    user = "root"
    password = "root"
    minConn = 5
    maxConn = 30
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}

3.2 registry.conf

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  #TODO 配置为nacos
  type = "nacos"

#TODO 设置你自己的nacos即可
  nacos {
    application = "fsp_test_group"
    serverAddr = "localhost:8848"
    namespace = "public"
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = 0
    password = ""
    cluster = "default"
    timeout = 0
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

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

 nacos {
    serverAddr = "localhost:8848"
    namespace = "public"
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    appId = "seata-server"
    apolloMeta = "http://192.168.1.204:8801"
    namespace = "application"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}

4. 启动 (先启动nacos,然后启动seata)

4.1 seata 启动

bin 目录下 seata-server.bat 直接双击

4.2 启动闪退解决

  1. 提示没有logs文件夹
    在这里插入图片描述
    解决:在bin同级目录下新建logs文件夹,在logs中新建seata_gc.log
  2. 如果还是闪退的话就新建环境变量,path里面直接 E:\seata\bin,这个路径为seata目录

5. 配置Springboot

5.1 pom.xml

		<!--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>
            <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.2.0</version>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.2.0</version>
        </dependency>

        <!--openFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--web-actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--mysql-druid mybatis-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        

5.2 配置文件

application.yml

server:
  port: 2001

spring:
  application:
    name: seata-order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/seata_order?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: root

feign:
  hystrix:
    enabled: false

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.hbsi.entity

# seata的配置在这里
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: my_test_tx_group

5.3 必须要配置 DruidDataSource 数据源,不配就报错

@Configuration
public class DBConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
}

6. 使用 @GlobalTransactional 注解进行分布式事务管理

在这里插入图片描述

seata 事务失效常见场景

1. 无法获取XID

在每个微服务中调用 RootContext.getXID() 方法检查XID是否一致

1.1 解决方法1:

需要引用spring-cloud-starter-alibaba-seata依赖。这个依赖里才有xid传递的功能。 seata-spring-boot-starter依赖,并没有传递功能

1.2解决方法2:

在调用各个微服务时,直接将XID进行手动传参绑定RootContext.bind(XID);

2. Feign调用了fallback降级或异常处理

手动回滚 :GlobalTransactionContext.reload(RootContext.getXID()).rollback()
手动提交:GlobalTransactionContext.reload(RootContext.getXID()).commit()

undo_log表有脏数据

清除undo_log表以及seata持久化数据库的brach_table、global_table、lock_table、undo_log表中的脏数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Seata1.2.0配置及分布式事务失效解决 的相关文章

  • 在Java中确定特定字体是否可以呈现特定字符

    Java中有没有办法确定特定字体是否可以呈现特定字符 Try Font f you have your font Character c Nun N in Farsi if f canDisplay c int gcode f getMis
  • 如何设置 JSlider 的大小?

    我在网上搜索了此问题的解决方案 但没有找到任何有效的方法 我在 JPanel 中有一个垂直 JSlider 它使用 GridBagLayout 和 GridBagConstraints 将对象定位在面板上 目前我有以下代码 gbc grid
  • Java 自动类型提升

    我引用 Herbert Schildt 的话 JAVA 完整参考第 8 版 第4章 操作员 当您转移时 Java 自动类型提升会产生意想不到的结果byte and short价值观 如你所知 byte and short价值观被提升为int
  • 将 WordprocessingMLPackage 保存到 ByteArrayInputStream

    如何将 org docx4j openpackaging packages WordprocessingMLPackage 实例保存到 ByteArrayInputStream 中 然后可以从服务器下载它 Thanks 您无法保存到Byte
  • Java图形图像

    嘿 我在 Jpanel 中添加以下图像 msu footprints org 2011 Aditya map jpg http msu footprints org 2011 Aditya map jpg 然后添加多边形 int x new
  • 在 Xcode 4 中编译 Java

    我知道这个问题已经流传了很长时间 Xcode 4 中的 Java 我不需要任何建议 Eclipse Netbeans 例如 我只想在 XCode4 而不是 3 中编译一些简单的 Java 代码 我设法创建了一个文件 正如预期的那样 语法和一
  • JNLP 作为 HTML 页面中的 Applet

    我试图在 HTML 页面中运行 JNLP 但 java 插件不运行 JNLP 只运行 Applet 这是我的代码
  • spring-data-jpa 不从 oracle.jdbc.driver.forwardonlyreswultset 进行转换

    我正在连接到 oracle 数据库 我刚刚解决了依赖问题 在以下网址中有所需的代码 如存储库 实体等 spring data jpa 1 11 16 带游标的存储过程 https stackoverflow com questions 53
  • 如何检查一个类没有参数构造函数

    Object obj new Object try obj getClass getConstructor catch SecurityException e e printStackTrace catch NoSuchMethodExce
  • 泛型方法调用重载方法的问题

    我遇到了有趣的事情 在 Java 和 C 中工作相同 Java代码 public class TestStuff public static void main String args Printer p new PrinterImpl p
  • Spring Boot - NoClassDefFoundError:ch/qos/logback/classic/Level

    我创建了一个普通的 Spring Boot 应用程序 1 5 9 RELEASE 但是当我Run As gt Spring Boot App 在 Eclipse Oxygen 中 我明白 SLF4J Failed to load class
  • Spring Boot - 处理 JSON 或 HTML 的错误控制器

    我有一个春季启动应用程序 我有一个自定义错误控制器 它映射到使用ErrorPage映射 这些映射主要基于 HTTP 状态代码 并且通常只是适当地呈现 HTML 视图 例如我的映射 Configuration class ErrorConfi
  • JUnit 测试时排除 @Component 类的过滤器?

    是否可以排除 Component带注释的类 我想从 JUnit 测试中排除一个特殊的类 我的项目有一个类xEventHandler注释为 Component我不希望 spring 在 junit 测试时使用这个类 我的应用程序 TestCo
  • ActionBarActivity getSupportActionBar().hide() 抛出 NullPointerException

    Call if getSupportActionBar null getSupportActionBar hide 要不就 getActionBar 在 android support v7 app ActionBarActivity 我得
  • Tomcat web.xml 文档

    我在将 Java 应用程序部署到 Tomcat 时遇到一些问题 我想查看 web xml 的文档在哪里 我好像找不到啊 我正在使用标准 web xml 但我想知道所有特定 xml 标签的含义 当然 通常使用标准的 web xml 就可以了
  • Android - ViewRootImpl$CalledFromWrongThreadException

    我正在使用this http savagelook com blog android display images from the internet in android 显示来自互联网的图像 但它会抛出如下错误 04 12 13 45
  • 将工具栏设置为片段中的操作栏

    我想将我的工具栏设置为操作栏 但由于您的工具栏是布局元素 因此它必须位于您的布局中 现在我的布局在我的片段中 我在布局中添加了工具栏 并在片段中调用它 Toolbar Toolbar toolbar Toolbar getActivity
  • String类如何重写+运算符?

    为什么在 Java 中 当 String 是一个类时 您可以使用 运算符添加字符串 在里面String java代码我没有找到这个运算符的任何实现 这个概念违反了面向对象吗 我们看一下Java中的以下简单表达式 int x 15 Strin
  • Retrofit 2 - 在 api 级别添加标头的优雅方式

    我的改装2 2 0 2当前 客户端需要向请求添加自定义标头 我正在使用一个Interceptor将这些标头添加到所有请求中 OkHttpClient httpClient new OkHttpClient httpClient networ
  • sun.* 包发生了什么

    我在 JDK 7 文档中没有找到任何关于sun 包 是否已弃用 但替代品是什么 For eg sun reflect 已被弃用 那么现在有什么选择呢 如果有人可以发布已弃用的软件包和可用的新选项 那就太好了 Note I succeded

随机推荐