seata组件——分布式全局事务

了解更多SpringCloudAlibaba系列:深入了解构建分布式微服务架构的利器:Spring Cloud Alibaba-CSDN博客

介绍

 seata官网:https://seata.io/zh-cn/

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

在单体应用架构中,当业务方法需要执行一组sql时,需要保证数据的一致性也就是所谓的ACID数据库四大范式,此时需要@Transaction来开启事务,但是@Transaction注解只能保证本地服务的事务,而在分布式架构中,服务与服务之间进行数据调用是避免不了的,但是由于@Transaction只能维持当前服务的的事务,而不能维持当前服务之外的事务,所以当需要回滚或提交多个服务的事务时,只有本地的事务会提交或回滚,导致其他服务的数据出现错误。所以在分布式先架构中,需要使用Seata解决分布式的应用场景;


AT模式原理详解

在学习seata之前先安装seata,为了方便展示安装步骤放在了文章末尾,请先进行安装在学习;

在上面提到Seata 提供了 AT、TCC、SAGA 和 XA 事务模式,在这四种模式中功能最强大的当属AT模式,该模式实现全局事务,对代码是无侵入实现的,这也是成为官网和企业开发中主推的原因,所以在这只介绍AT模式,先了解一下模式中的几个重要角色;

模式角色:

官网:

Transaction Coordinator(TC)
事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。


Transaction Manager(TM)
控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议,TM定义全局事务的边界。


Resource Manager(RM)
控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。RM负责定义分支事务的边界和行为。

事务协调器TC:也就是seata服务,负责维持全局事务,也成为事务的协调者;

事务发起者TM:负责开启一个全局事务,并最终发起全局提交或全局回滚的决议,也就是通过seata的注解@GloubTransactional标识需要开启事务的业务方法;

分支事务RM:被seata的注解所表示的方法中,所有需要参与事务的服务,也称为事务的参与者;

模式原理

  1. 当请求执行到@GloubTransactional注解标识的方法时,TM事务发起者会告诉TC事务协调者开启一个全局事务,需要注意的是TM只是事务的发起者不是事务的开启者;
  2. TC事务协调者收到TM事务发起者要求开启一个全局事务后会开启全局事务,并向全局事务gloub_table表中生成一条数据,该数据记录了全局事务信息(如 XID、事务状态等)xid字段作为全局事务的标识,然后将xid字段返回给事务的发起者TM;
  3. TM收到xid之后进行服务调用,并将xid传递给事务的参与者RM;
  4. 当事务参与者RM收到xid之后开始,开始执行sql并处理sql(处理sql的原理参考RM实现细节),将sql处理信息记录在分支事务表undo_log中,目的是为了在需要回滚事务时进行逆向操作;信息;
  5. 随后RM带着xid上报TC,TC收到后创建分支事务,并在branch_table表中记录分支事务的
  6. 当分支事务处理完sql之后到达TM事务边界,如果分支事务执行过程没有异常,TM会想TC提交xid,如果有异常TM带着xid向TC发起全局事务回滚;
  7. TC接收到TM的提交请求后通知分支事务RM删除undo_log日志,同时TC删除全局事务或分支事务,如果TC收到TM的是回滚请求,将通知分支事务RM根据undo_log日志记录进行数据逆向还原并删除undo_log记录,TC同时删除全局事务及分支事务;

图片来源于网络

 RM实现细节:

  1. 生成sql分析器对服务调用方法中的sql进行拆解;
  2. 根据分析得到的条件,把操作前的数据作为源数据查出来,放入到查询前置快照beforeImage中,便于回滚操作逆向恢复数据;
  3. 执行sql;
  4. sql执行之后,把操作后的数据在查询出来,放入查询后置快照aftreImage中,然后写入到undo_log表中,然后进行分支事务注册,并上报全局事务生成全局事务锁;
  5. 当分支事务的undo_log记录完成之后提交分支事务,并向TC事务协调者进行汇报分支事务;

图片来源于网络


使用教程

1、在需要使用全局事务的服务中添加依赖

<!--seata依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

2、在application配置文件中配置seata相关配置

第一部分

spring:
  thymeleaf:
    cache: true
  datasource:
    url: jdbc:mysql://192.168.231.131:3306/order-seata?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  application:
    name: alibaba-order-server
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
    # 添加 seata的分组
    alibaba:
      seata:
        tx-service-group: xigai

# seata配置:spring.cloud.alibaba.seata.tx-service-group=自己在配置中设置的分钟

第二部分

seata:
  registry:   # 配置seata的注册中心
    type: nacos
    nacos:
      server-addr: ${spring.cloud.nacos.discovery.server-addr}
      application: seata-server
      username: ${spring.cloud.nacos.discovery.username}
      password: ${spring.cloud.nacos.discovery.username}
      group: SEATA_GROUP
  config:   # seata 配置中心,读取seata在nacos中的seata client配置
    type: nacos
    nacos:
      server-addr: ${spring.cloud.nacos.discovery.server-addr}
      username: ${spring.cloud.nacos.discovery.username}
      password: ${spring.cloud.nacos.discovery.username}
      group: SEATA_GROUP

3、在需要开启全局事务的业务方法上添加注解@GlobalTransactional

    @GlobalTransactional
    @Override
    public OrderInfo orderAdd(OrderInfo orderInfo) {
        try {
            final int orderCont = orderInfoMapper.insert(orderInfo);
            orderInfo.setOrderMsg("新增订单:"+orderCont);
            System.out.println("新增订单:"+orderCont);
            TimeUnit.SECONDS.sleep(5);

            // 扣减库存
            String isReduce = feignStockService.reduce(Integer.valueOf(orderInfo.getStockId()));
            System.out.println(isReduce);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // int a=1/0;
        return orderInfo;
    }

 4、服务调用参考feign组件的调用服务:feign组件调用远程服务-CSDN博客


安装步骤

1、进入下载地址下载对应版本:https://github.com/seata/seata/releases

2、下载好之后进入seata的conf目录打开file.conf配置文件修改信息存储方式,seata作为服务协调者TC有多种信息存储方式,我选择用db数据库的方式进行存储,选择数据存储的方式需要先把数据库和表提前创建好,下载路径在下面;

 

 3、下载数据库需要的表,建议把整个工程下载下来,地址:https://github.com/seata/seata/

4、集成nacos实现配置管理,修改seata目录下的conf文件中的 registry.conf 文件

5、修改刚才下载工程的配置文件数据源,script文件夹可以单独提出来放在seata的目录下和conf等文件夹同级,但是文件路径包括父级文件路径都不能存在空格,我的seata的父级文件夹存在空格,所以我直接放在d盘下面了,这个对路径位置存放没有要求,只对文件路径是否包含空格有要求

 

 

5、执行脚本把配置文件注册到nacos配置中心

 

 

 

成功出来就安装完成了 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值