Seata 的 AT 模式

本文介绍了如何在Springcloud中整合Seata的AT模式,包括数据库脚本的添加、服务依赖的管理、Springboot配置以及代码层面的改造,重点讲解了写隔离和读隔离的工作原理。
摘要由CSDN通过智能技术生成

目录

概述

Springcloud 整合 Seata

数据库脚本

服务依赖

Springboot 配置

代码改造

AT模式下的数据隔离

写隔离

读隔离


概述

   Seata 的 AT 模式是 Seata 的默认模式,它的原理是依赖于数据库事务,以数据库事务保证本地事务分支特性,结合 Seata的 Undo 日志记录做事务补偿,来实现的一种二阶段事务。总体来讲,Seata 的AT模式使用起来比较简单,对业务代码的侵入性比较低。

 Demo

   这里附上seata的学习代码demo,开箱即用。包含AT/TCC/XA等模式的使用案例https://download.csdn.net/download/lmj3732018/88864802

Springcloud 整合 Seata

数据库脚本

 AT 模式需要在每个本地事务分支所在的数据库中添加一个 undo_log 表,用于存储本地事务分支的事务记录。

数据库脚本地址:https://github.com/apache/incubator-seata/blob/v1.7.0/script/client/at/db/mysql.sql

服务依赖

  Seata 的依赖版本最好参照官网推荐的版本对照,否则,可能出现不兼容的一些问题,同时 Seata 客户端与服务端的版本也最好保持一致

 POM依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<!--nacos 注册中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
 
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
 
<!-- seata-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

Springboot 配置

seata:
  application-id: ${spring.application.name}
  # 这个值要与服务端 service.vgroupMapping.default_tx_group=default 相对应,服务端的值default与下面的 cluster: default 对应。
  tx-service-group: default_tx_group
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 192.168.122.120:8848
      namespace: seata-id
      group: SEATA_GROUP
      username: nacos
      password: nacos
      cluster: default
  config:
    type: nacos
    nacos:
      server-addr: 192.168.122.120:8848
      namespace: seata-id
      group: SEATA_GROUP
      data-id: seataServer.properties
      username: nacos
      password: nacos

代码改造

代码上的改造比较简单,只需在事务发起者的接口方法上添加一个@GlobalTransactional(name="createOrder",rollbackFor=Exception.class)注解。分支事务那边则不用做任何处理

 @Override
    //@Transactional
    @GlobalTransactional(name="createOrder",rollbackFor=Exception.class)
    public Order saveOrder(OrderVo orderVo) {
        log.info("=============用户下单=================");
        log.info("当前 XID: {}", RootContext.getXID());
         
        // 保存订单
        Order order = new Order();
        order.setUserId(orderVo.getUserId());
        order.setCommodityCode(orderVo.getCommodityCode());
        order.setCount(orderVo.getCount());
        order.setMoney(orderVo.getMoney());
        order.setStatus(OrderStatus.INIT.getValue());
     
        Integer saveOrderRecord = orderMapper.insert(order);
        log.info("保存订单{}", saveOrderRecord > 0 ? "成功" : "失败");
         
        //扣减库存
        storageFeignService.deduct(orderVo.getCommodityCode(), orderVo.getCount());
 
        if(true){
            throw new RuntimeException();
        }
 
        //扣减余额
        Boolean debit= accountFeignService.debit(orderVo.getUserId(), orderVo.getMoney());
 
//        if(!debit){
//            // 解决 feign整合sentinel降级导致Seata失效的处理
//            throw new RuntimeException("账户服务异常降级了");
//        }
         
        //更新订单
        Integer updateOrderRecord = orderMapper.updateOrderStatus(order.getId(),OrderStatus.SUCCESS.getValue());
        log.info("更新订单id:{} {}", order.getId(), updateOrderRecord > 0 ? "成功" : "失败");
         
        return order;
         
    }

AT模式下的数据隔离

写隔离

AT模式下通过全局锁来保证写操作的隔离性,避免产生脏读。当全局事务A在操作某一条记录时,会给这条记录加一个全局锁,所谓的全局锁实际是指这条记录的ID,当本地事务提交,而全局事务没提交时。我们虽然通过直接操作数据库可以看到这条提交的数据,但是当开启另一个全局事务去操作这条数据时,则会先判断全局锁的存在,如果存在则默认将当前事务回滚(也可修改策略为不断尝试获取全局锁)。

读隔离

AT模式默认情况下,如果数据库的隔离级别为“读已提交”,则全局事务的隔离级别为"读未提交"。AT模式仅仅对 带有 "select  for update"的语句会检查全局锁。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季风泯灭的季节

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值