首页 > 其他分享 >Springboot整合Seata实现分布式事务

Springboot整合Seata实现分布式事务

时间:2023-04-05 20:24:22浏览次数:62  
标签:事务 Springboot seata 回滚 eureka Seata file TC 分布式

前言

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata 配置非常灵活,支持多种注册中心、配置来源(配置中心)和持久化方式。本文选择 eureka 作注册中心,本地文件作配置,用 MySQL 作持久化。

名词解释

  • TC (Transaction Coordinator) - 事务协调者
    维护全局和分支事务的状态,驱动全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器 / 事务参与者
    定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器 / 事务参与者
    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
  • TM 和 RM 都可以看成我们的业务服务,而 TM 是分布式事务开始的地方,调用链如 TM — RM — RM ~。

TC 配置

  • TC GitHub Releases 下载编译好的包解压。
  • 修改 /conf/registry.conf 配置注册中心和配置来源
registry {
  type = "eureka"
  
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "seata-server"
    weight = "1"
  }
}

config {
  type = "file"
  
  file {
    name = "file.conf"
  }
}
  • 因为使用配置类型为 file, 修改对应 /conf/file.conf,指定 db 作为存储,并配置好数据库地址
## transaction log store, only used in seata-server
store {
  ## store mode: file、db、redis
  mode = "db"
 
  ## 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"
    ## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection param
    url = "jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true"
    user = "root"
    password = "root"
  }
}
  • 注册(file 、nacos 、eureka、redis、zk、consul、etcd3、sofa)、配置(nacos 、apollo、zk、consul、etcd3)、存储(file、db、redis)方式有很多种方式,解压包里 conf/ 下配置文件各种配置方式都列出来了,只需要指定使用的方式,再修改对应类型的配置就行了。

  • 创建数据库执行 TC MySQL 脚本

  • 执行 bin/ 下脚本 seata-server.sh/bat 启动 TC 服务。

TM / RM 配置

  • pom.xml 添加依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-seata</artifactId>
    <version>${spring-cloud-alibaba-seata.version}</version>
</dependency>
  • resources/ 增加 registry.conf 配置文件。同 TC 一样指明使用 eureka 作注册中心,本地 file.conf 作配置来源
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"
  
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "seata-server"
    weight = "1"
  }
}

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

  file {
    name = "file.conf"
  }
}
service {
  #transaction service group mapping
  vgroupMapping.my_test_tx_group = "seata-server"
}

AT (Automatic Transaction) 模式

  • AT 是 2PC 方案的一种实现。TM 先执行本地事务,并在 undo_log 表记录回滚日志但不提交,向 TC 申请全局锁成功后一起提交。
  • 紧接着调用后面的 RM,RM 同样记录回滚日志直接提交,不需要申请全局锁。
  • 最后所有参与者事务都执行成功,则 TC 通知提交,参与者会删掉回滚日志;如果有参与者执行失败通知 TC 后,TC 会通知参与者回滚,参与者根据日志回滚数据。
  • 全局锁是独占锁,占用期间并行的请求会在申请锁那一步等待。
  • 跟 2PC 比,AT 先提交了本地事务,不会长时间占用资源。

在这里插入图片描述

  • 使用时只需要在 TM 服务事务方法上加注解 @GlobalTransactional,调用链后面的 RM 无需处理。
@GlobalTransactional
public void purchase(String userId, String commodityCode, int orderCount) {
    storageFeignClient.deduct(commodityCode, orderCount);
    orderFeignClient.create(userId, commodityCode, orderCount);
    if (!validData()) {
        throw new RuntimeException("账户或库存不足,执行回滚");
    }
}

TCC (Try Confirm Cancel) 模式

Seata TCC 三部操作对应 prepare、commit、rollback。

在这里插入图片描述

  • TM / RM 业务类需要一个接口,接口加上注解 @LocalTCC;业务接口上加 @TwoPhaseBusinessAction 并指明三个阶段执行的方法。然后实现类实现接口方法的具体逻辑。
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;

@LocalTCC
public interface ITccService {

    /**
     * Prepare
     */
    @TwoPhaseBusinessAction(name = "tccTest", commitMethod = "tccTestCommit", rollbackMethod = "tccTestRollback")
    String tccTest(@BusinessActionContextParameter(paramName = "param1") String param1,
                   @BusinessActionContextParameter(paramName = "param2") boolean param2);

    /**
     * Commit
     */
    boolean tccTestCommit(BusinessActionContext businessActionContext);

    /**
     * Rollback
     */
    boolean tccTestRollback(BusinessActionContext businessActionContext);
}
  • TM 则需要另外在调用事务方法的地方加注解 @GlobalTransactional。需要注意的是这个不能加到 Service 里面 。
@GlobalTransactional
@RequestMapping("/tcc/rollback")
public String purchaseRollback() {
    iTccService.tccTest(ThreadLocalRandom.current().nextInt() + "", true);
    return "全局事务提交";
}

如何解决 TCC 空回滚 幂等 悬挂问题?

增加事务控制表来解决,表主要包含全局事务id(transaction_id)、分支事务id(branch_id)、状态(state:1-已初始化、2-已提交、3-已回滚)。

  • 空回滚

try 未执行的情况下执行了 cancel,比如开启全局事务后执行 try 超时了,但事务已经开启,需要推进到终态,因此 TC 通知执行 cancel,从而形成空回滚。

解决方案:执行 try 时在事务控制表插入一条记录,标记为1-已初始化。cancel 时检查记录存在,正常回滚;如果不存在,执行空回滚。

  • 悬挂

cancel 优先 try 执行,同样是 try 超时,然后执行了空回滚后 try 开始执行。这种情况下应该让 try 不执行。

解决方案 :cancel、commit 的时候判断如果事务控制表没记录则插入对应状态的记录,try 执行前如果发现有记录则不执行。

  • 幂等

TC 在通知参与者提交/回滚的时候,如果没收到反馈会重复通知。

解决方式:参与者处理完后修改事务控制表中的状态,处理前判断状态如果处理过,则不做任何处理。

参考链接

Seata 官网

Seata 中文文档

GitHub - TC 服务 Releases

GitHub - 官方使用例子程序

GitHub - Spring Cloud 快速集成 Seata

GitHub - 本文代码地址

标签:事务,Springboot,seata,回滚,eureka,Seata,file,TC,分布式
From: https://www.cnblogs.com/shuiyao3/p/17290762.html

相关文章

  • Springboot整合TX-LCN实现分布式事务
    前言TX-LCN是一款国产分布式事务协调框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。本文讲解如何使用Springboot作为基础,来配置使用TX-LCN。需要MySQL和Redis。名词解释TM(Tx-Manager/TransactionManager)事务协调者TC(Tx-Client......
  • Springboot整合Apollo配置中心
    前言参考这一篇在Linux部署Apollo配置中心可以搭建出一套Apollo配置中心服务,我们在这里重点看看Springboot如何整合Apollo,将配置交给配置中心管理,并在修改后及时生效到服务上。我们模拟工作中的开发(development,DEV)和生产(production,PRO)两套环境,在下面例子中会实现不同环境下配......
  • Springboot+ElasticJob-Lite实现集群任务调度
    前言ElasticJob-Lite是集群环境下应用(比如SpringCloud微服务)任务调度的解决方案。集群部署的时候,一个定时任务会有多个进程执行,如果不进行任何处理,会导致任务触发的时候每个进程重复执行一次。解决办法有两种:一种是加锁,保证同时只有一个进程执行任务,比如用分布式锁,或者用任务调......
  • Springboot+Mysql 图书管理系统【源码+sql】
    java项目学生图书管理系统(源码+数据库文件)技术框架:java+springboot+mysql后端框架:SpringBoot、SpringMVC、MyBatisPlus前端界面:Thymeleaf、BootStrap、jQuery系统共分为三种用户系统主要功能:系统设计三个角色,学生端,管理员端,系统管理员端1.普通用户书籍查询、书籍借阅......
  • GFS分布式文件系统
    一、文件系统简介1.1文件系统的组成接口:文件系统接口功能模块(管理、存储的工具):对对象管理里的软件集合对象及属性:(使用此文件系统的消费者)1.2文件系统的作用从系统角度来看,文件系统时对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统主要负责为......
  • 基于SpringBoot+Vue+ElementUI的在线考试系统(可做毕设)
    项目简介青云是一套麻雀虽小但五脏俱全的在线考试系统。采用了目前主流的技术栈SpringBoot+Vue+ElementUI,并进行了前后端分离。对于事务和锁都有应用,非常适合学习练手。项目演示项目演示地址:http://xuezhabiji.com:5000账号:admin密码:admin代码获取:github:https://github.com......
  • GFS分布式文件系统
    一、GlusterFS概述1.1GlusterFS简介GlusterFS是一个开源的分布式文件系统。由存储服务器、客户端以及NFS/Samba存储网关(可选,根据需要选择使用)组成。没有元数据服务器组件,这有助于提升整个系统的性能、可靠性和稳定性。 传统的分布式文件系统大多通过元服务器来存储元......
  • Springboot 系列 (29) - Springboot+HBase 大数据存储(七)| Springboot 项目通过 Phoeni
    Phoenix是HBase的开源SQL皮肤,通过Phoenix可以使用标准JDBCAPI代替HBase客户端API来创建表,插入数据和查询HBase数据。Phoenix会把SQL编译成一系列的Hbase的scan操作,然后把scan结果生成标准的JDBC结果集,其底层由于使用了Hbase的API,协处理器,过滤器。Pho......
  • springboot +vue2.x实现音乐网站
    1pom文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache......
  • 分布式锁和事务
    1.分布式锁的实现方式?1.基于数据库实现-mysql行锁2.基于zookeeper-CP模式3.基于Redissetnx实现-AP模式4.Redis框架Redission,RedisLock要求:保证一致性zk实现分布式锁保证可用性redis实现分布式锁2.Zookeeper实现分布式锁原理:zookeeper节点路径不能重复,保证唯一性......