使用Seata 1.5.2 版本使用以及客户端 yml 的使用姿势

关于替换Seata 事务 1.5.2 框架实现事项

引序(简单介绍一下)

Seata 提供了两种主要的事务模式:AT(Automatic Transaction)模式和 TCC(Try-Confirm-Cancel)模式。它们有一些差异,选择哪种模式取决于你的具体需求和业务场景。

  1. AT 模式(自动事务模式):
    • 特点: AT 模式是一种基于数据库的分布式事务模式,它依赖数据库的支持来保证全局事务的一致性。
    • 工作原理: 在分布式事务中,AT 模式通过在参与者服务中对数据库操作进行undo和redo的日志记录,以实现全局事务的一致性。在全局提交阶段,各参与者服务执行事务的提交或回滚操作。
    • 适用场景: 适用于业务场景相对简单、对性能要求较高的情况,且数据库支持XA协议。
  2. TCC 模式(Try-Confirm-Cancel 模式):
    • 特点: TCC 模式是一种更加灵活的分布式事务模式,它将一个业务操作拆分为三个阶段:Try、Confirm、Cancel,允许开发者手动编写业务逻辑来处理每个阶段。
    • 工作原理: 在 TCC 模式中,每个业务操作被分解为三个步骤:Try(尝试执行业务)、Confirm(确认执行业务)、Cancel(取消执行业务)。这三个步骤由开发者编写具体的业务逻辑来完成。
    • 适用场景: 适用于业务场景复杂、对业务逻辑的控制要求高的情况,但需要开发者编写更多的业务逻辑代码。

选择模式的依据:

  • 业务复杂度: 如果业务逻辑较为简单,不需要手动编写事务的 Try、Confirm、Cancel 逻辑,AT 模式可能更为适用。而对于复杂的业务逻辑,TCC 模式更具灵活性。
  • 性能需求: AT 模式通常对性能要求较高,因为它依赖数据库的支持来完成事务操作。如果对性能有较高要求,AT 模式可能更为适用。
  • 业务一致性: TCC 模式对业务的一致性有更好的控制,开发者可以更精细地处理各个阶段的业务逻辑。如果业务一致性要求高,TCC 模式可能更合适。

在实际项目中,根据具体的业务需求和系统特点进行选择。有些项目可能会选择混合使用,根据具体场景选择不同的事务模式。 Seata 还在不断演进,未来可能会有更多的事务模式和功能,可以根据项目的发展和需求进行选择。

背景是因为当前项目使用的springboot版本实在是太低了,多次尝试之后就只能兼容seata 的 1.4.2 和 1.5.2 版本了,这两个版本的服务端sql脚本有所区别大家请注意。

区别:
seata 1.4.2 使用 registry.conf 和 file.conf 部署配置文件
seata 1.5.2 使用 yml 部署配置文件

seata 的各版本部署可以直接 docker 很简单傻瓜式这里就不说了,seata服务端配置文件也和客户端进来一致就行 有 yml 或者 file.conf 两种姿势。我这里就讲yml的姿势。

1、初始化数据库

Seata 服务端配置3张配置表(必选)

Seata 客户端配置1张日志表(必选)


------------------------------------------服务端sql-------------------------
CREATE TABLE IF NOT EXISTS `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`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(200),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;


-------------客户端sql---------------


-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

--有一个小坑 lock_table 表的 table_name 字段长度官方默认32位,我们业务表挺长的,我就改成了 200长度,需要的可以自己再调整。
 

2、导入依赖


        <!-- dependencys 中新加 seata相关 start -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>1.5.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.5.2</version>
        </dependency>
		<!-- 这里想用客户端配置yml必须要引入 seata-spring-boot-starter 否则忽略 -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.5.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- seata相关 end -->

        <!--解决jackson报错问题 start -->
        <dependency>
            <groupId>com.esotericsoftware.kryo</groupId>
            <artifactId>kryo</artifactId>
            <version>2.24.0</version>
        </dependency>

        <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
            <version>4.0.2</version>
        </dependency>

        <dependency>
            <groupId>de.javakaffee</groupId>
            <artifactId>kryo-serializers</artifactId>
            <version>0.44</version>
        </dependency>
        <!--解决jackson报错问题 end -->

<!-- build 中 非必选 -->
<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>*.conf</include>
                </includes>
                <excludes>
                    <exclude>**/*.yml</exclude>
                    <exclude>**/*.properties</exclude>
                    <exclude>**/*.xml</exclude>
                </excludes>
            </resource>
        </resources>

3、实现数据源代理


package ***;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;

/**
 * @author: xll
 * @Date: 
 * @Description:
 */
@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }

    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
        return new DataSourceProxy(druidDataSource);
    }
}:
可能出现的问题:dataSource 数据源出现循环依赖,原因是因为seata需要代理数据源和原来的数据源有冲突,解决方法是手动注入数据源bean ,在启动类上关闭数据源的自动注入,通过以上 DataSourceConfiguration 手动注入
    
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 

4、使用分布式事务注解

@GlobalTransactional 

    
注意:
1、name 如果在同一次调用中的多个微服务中使用不同的 name 参数,会导致这些微服务的操作不属于同一个全局事务。这样会破坏了分布式事务的一致性,可能引发数据不一致的问题。
2、timeoutMills 超时时间 6000060 秒)
如果多个服务都设置了 timeoutMills 参数,则 Seata 会选择其中设置值最小的超时时间作为全局事务的超时时间。
如果有的服务没有设置 timeoutMills 参数,则 Seata 会选择设置了该参数的服务中设置值最小的超时时间作为全局事务的超时时间。
 

5、Seata 配置文件

配置文件有两种配置姿势,按照官方的文档来实现将seata的客户端配置保存在项目下的 registry.conf 和 file.conf 文件中且进来保持和服务端配置一样。

6、客户端使用yml版本

配置客户端yml ,不再需要 registry.conf 和 file.conf


spring:
  cloud:
    alibaba:
      seata:
        tx-service-group: "tx-service-group"
        
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: "seata-service"
  access-key:
  secret-key:
  enable-auto-data-source-proxy: true
  data-source-proxy-mode: AT
  server:
    undo:
      log-serialization: kryo
  store:
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      ## 服务端数据库地址
      url: ""
      user: ""
      password: ""
      min-conn: 5
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 100
      max-wait: 5000
  client:
    tm:
      commit-retry-count: 5
      rollback-retry-count: 5
      default-global-transaction-timeout: 600000
      degrade-check: false #关闭熔断
      degrade-check-period: 2000
      degrade-check-allow-times: 10
      interceptor-order: -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
    undo:
      data-validation: true
      log-serialization: kryo
      log-table: undo_log
      only-care-update-columns: true
      compress:
        enable: true
        type: zip
        threshold: 64k
    load-balance:
      type: XID
      virtual-nodes: 10
  service:
    vgroup-mapping:
      tx-service-group: "seata-service"
    enable-degrade: false
    disable-global-transaction: false
    disableGlobalTransaction: false
  transport:
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      server-executor-thread-prefix: NettyServerBizHandler
      share-boss-worker: false
      client-selector-thread-prefix: NettyClientSelector
      client-selector-thread-size: 1
      client-worker-thread-prefix: NettyClientWorkerThread
      worker-thread-size: default
      boss-thread-size: 1
    type: TCP
    server: NIO
    heartbeat: true
    serialization: seata
    compressor: none
    enable-tm-client-batch-send-request: false
    enable-rm-client-batch-send-request: true
    rpc-rm-request-timeout: 15000
    rpc-tm-request-timeout: 30000
  config:
    type: file
    custom:
      name:
  registry:
    type: eureka
    eureka:
      weight: 1
      service-url: http://localhost:1234/eureka
      application: "seata-service"
  log:
    exception-rate: 100        


注:tx-service-group名称直接对应seata.service.vgroup-mapping名;
seata.service.vgroup-mapping.tx-service-group 直接对应 registry.conf配置文件中 eureka.application名称。

Seata XID 事务传播的源码:

SeataFeignClient.execute 重写了feign调用,然后把xid放到requestHeader里面传递给下游服务
SeataHandlerInterceptorConfiguration 实现了 WebMvcConfigurerAdapter 的 preHandle 在里面的消息头获取到xid

关于服务自动降级策略的具体实现介绍:

首先通过读取client.tm.degradeCheck是否为true,决定是否开启自检线程.随后读取degradeCheckAllowTimes和degradeCheckPeriod,确认阈值与自检周期.
假设degradeCheckAllowTimes=10,degradeCheckPeriod=2000
那么每2秒钟会进行一个begin,commit的测试,如果失败,则记录连续失败数,如果成功则清空连续失败数.连续错误由用户接口及自检线程进行累计,直到连续失败次数达到用户的阈值,则关闭Seata分布式事务,避免用户自身业务长时间不可用.
反之,假如当前分布式事务关闭,那么自检线程继续按照2秒一次的自检,直到连续成功数达到用户设置的阈值,那么Seata分布式事务将恢复使用

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Seata 1.5.2是一个开源的分布式事务解决方案,而Nacos则是一个开源的动态服务发现、配置管理和服务管理平台。集成Seata 1.5.2与Nacos可以使得我们在应用程序中更方便地使用分布式事务功能,并且能够动态地管理配置和服务。 首先,集成Seata 1.5.2和Nacos需要进行一些准备工作。我们需要在应用程序中引入Seata 1.5.2和Nacos的相关依赖包,并进行相应的配置。在Seata 1.5.2的配置中,我们需要指定Nacos作为注册中心和配置中心。 其次,集成Seata 1.5.2和Nacos需要对应用程序进行适当的修改。在应用程序中,我们需要使用Seata 1.5.2提供的事务管理接口来控制分布式事务的开始、提交和回滚。同时,我们还需要修改数据库连接配置,确保Seata 1.5.2能够正确地拦截和管理数据库操作。 最后,集成Seata 1.5.2和Nacos还需要进行一些额外的配置。我们需要在Nacos中注册Seata 1.5.2提供的事务协调器服务,并将其配置信息与应用程序进行关联。这样,当应用程序启动时,Seata 1.5.2将会自动从Nacos中获取事务协调器的地址,并与其建立连接。 总结而言,集成Seata 1.5.2和Nacos可以使得我们更方便地使用分布式事务功能,并且能够动态地管理配置和服务。通过适当的配置和修改,我们可以在应用程序中使用Seata 1.5.2提供的事务管理接口,并且将事务协调器的地址信息存储在Nacos中,进一步简化了分布式事务的使用和管理。这样的集成方案可以提高应用程序的可靠性和可伸缩性,同时也减轻了开发和维护的工作量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值