seata中如何使用AT和TCC模式

2023-05-21

本篇文章为大家展示了seata中如何使用AT和TCC模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

seata的AT和TCC模式的使用

名词解释

图片来自 Seata解析-TM、RM、TC交互流程梳理

TC (Transaction Coordinator) - 事务协调者

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

TM (Transaction Manager) - 事务管理器

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

RM (Resource Manager) - 资源管理器

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

模式介绍

AT

  • 基于支持本地 ACID 事务的关系型数据库。

  • Java 应用,通过 JDBC 访问数据库。

两阶段提交协议的演变:

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

  • 二阶段:

    • 提交异步化,非常快速地完成。

    • 回滚通过一阶段的回滚日志进行反向补偿。

TCC

一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段 prepare 行为

  • 二阶段 commit 或 rollback 行为

TCC 模式,不依赖于底层数据资源的事务支持:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。

  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。

  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

使用

配置

1. 启动seata-server

参照官网部署教程,启动成功后可以看到这句 Server started, listen port: 8091,注意这个端口不是用来通过http访问的, 这个端口是用来协调应用分布式事务的,直接通过浏览器访问会报错。

SLF4J: A number (18) of logging calls during the initialization phase have been intercepted and are
SLF4J: now being replayed. These are subject to the filtering rules of the underlying logging system.
SLF4J: See also http://www.slf4j.org/codes.html#replay
09:54:04.048  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is registry
09:54:04.055  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is C:\Server\seata-server-1.4.2\conf\registry.conf
09:54:04.119  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is file.conf
09:54:04.119  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is C:\Server\seata-server-1.4.2\conf\file.conf
09:54:06.578  INFO --- [                     main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
09:54:07.304  INFO --- [                     main] i.s.core.rpc.netty.NettyServerBootstrap  : Server started, listen port: 8091
2. 添加依赖
<!-- 分布式事务seata -->
<dependency>
    <groupid>com.alibaba.cloud</groupid>
    <artifactid>spring-cloud-starter-alibaba-seata</artifactid>
</dependency>

<!-- 序列化方式选择的kryo, 在使用jackson和fastjson时,对时间的序列化一直出问题 -->
<dependency>
    <groupid>de.javakaffee</groupid>
    <artifactid>kryo-serializers</artifactid>
    <version>${kryo.serializers.version}</version>
</dependency>
3. 添加配置
seata:
  service:
  	# TC服务列表 仅注册中心为file时使用
    grouplist:
      default : seata.server.cn:8091
    # 事务群组, service-goods-center为分组,配置项值为TC集群名
    vgroup-mapping:
      service-goods-center: default
    # 全局事务开关,默认false。false为开启,true为关闭
    disable-global-transaction: false
  # 视作分名
  tx-service-group: service-goods-center
  client:
    undo:
      # undolog的序列化方式, AT模式需要配置,因为AT模式数据库会有undo-log表
      log-serialization: kryo
4. 数据库配置

访问 seata数据库脚本 链接,找到对应版本和对应数据库类型的SQL脚本,在业务系统创建出来undo-log表。

1.3.0版本

CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) 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';

AT模式的使用

只需要在TM端服务方法上加上@GlobalTransactional注解,被调用RM端方法可以不用显式的声明@GlobalTransactional注解

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String insert() {
    service.insert();
    //放开以下注解抛出异常
    //throw new RuntimeException("服务AT测试回滚");
    return "success";
}

TCC的使用

1. 定义TCC接口

@LocalTCC一定需要注解在接口上,否则不生效,此接口可以是寻常的业务接口,只要实现了TCC的两阶段提交对应方法便可,TCC相关注解如下:

  • @LocalTCC 适用于SpringCloud+Feign模式下的TCC

  • @TwoPhaseBusinessAction 注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,去帮我们自动调用提交方法或者回滚方法。

  • @BusinessActionContextParameter 注解可以将参数传递到二阶段(commitMethod/rollbackMethod)的方法。

  • BusinessActionContext 便是指TCC事务上下文

/**
 * 这里定义tcc的接口
 * 这些一定要定义在接口上
 * 我们使用springCloud的远程调用
 * 那么这里使用LocalTCC便可
 *
 * @author tanzj
 */
@LocalTCC
public interface TccService {
 
    /**
     * 定义两阶段提交
     * name = 该tcc的bean名称,全局唯一
     * commitMethod = commit 为二阶段确认方法
     * rollbackMethod = rollback 为二阶段取消方法
     * BusinessActionContextParameter注解 传递参数到二阶段中
     *
     */
    @TwoPhaseBusinessAction(name = "insert", commitMethod = "commitTcc", rollbackMethod = "cancel")
    String insert(
            @BusinessActionContextParameter(paramName = "params") Map<string, string> params
    );
 
    /**
     * 确认方法、可以另命名,但要保证与commitMethod一致
     * context可以传递try方法的参数
     * 参数是固定的, 不可以增加或减少,
     */
    boolean commitTcc(BusinessActionContext context);
 
    /**
     * 二阶段取消方法
     * 参数是固定的, 不可以增加或减少
     */
    boolean cancel(BusinessActionContext context);
}
2. TCC接口的调用和实现
  • 在try方法中使用@Transational可以直接通过spring事务回滚关系型数据库中的操作,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。

  • 使用context.getActionContext("params")便可以得到一阶段try中定义的参数,在二阶段对此参数进行业务回滚操作。

  • **注意1:**此处亦不可以捕获异常(同理切面处理异常),否则TCC将识别该操作为成功,二阶段直接执行commitMethod。

  • **注意2:**TCC模式要开发者自行保证幂等和事务防悬挂

调用代码

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String insert() {
    log.info("xid = " + RootContext.getXID());
    //todo 实际的操作,或操作MQ、redis等
    tccDAO.insert(new HashMap&lt;&gt;());
    //放开以下注解抛出异常
    //throw new RuntimeException("服务tcc测试回滚");
    return "success";
}

混合使用

也没别的,默认使用的就是AT事务,别在同一个接口方法上添加TCC注解就行,可以通过AT方法嵌套TCC方法,注意不要通过this.xx()调用,这样会无法应用代理的增强。

mybatis-plus出现问题,解决方案

透过源码解决SeataAT模式整合Mybatis-Plus失去MP特性的问题</string,>

上述内容就是seata中如何使用AT和TCC模式,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注本站行业资讯频道。

《seata中如何使用AT和TCC模式.doc》

下载本文的Word格式文档,以方便收藏与打印。