springcloud整合seata的实现代码

作者:huan1993 时间:2022-04-26 23:49:49 

一、背景

在上一篇文章中,我们使用Seata整合了SpringBoot,在这篇文章中我们使用Seata整合SpringCloud。同时有了上一篇文章的基础,此处我们简单实现。

二、项目结构

springcloud整合seata的实现代码

三、实现功能:

完成用户下单操作,下单分为调用 账户服务 扣除余额,调用订单服务创建订单。

springcloud整合seata的实现代码

四、项目使用到的技术

Spring Cloud 、eureka、openfeign、seata 、nacos、druid、mybatis-plus

五、整合步骤

1、引入spring-cloud-starter-alibaba-seata jar包

<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
   <version>2021.1</version>
   <exclusions>
       <exclusion>
           <artifactId>seata-spring-boot-starter</artifactId>
           <groupId>io.seata</groupId>
       </exclusion>
   </exclusions>
</dependency>
<dependency>
   <groupId>io.seata</groupId>
   <artifactId>seata-spring-boot-starter</artifactId>
   <version>1.4.2</version>
</dependency>

springcloud整合seata的实现代码

参考文档: https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html

2、涉及到的业务库操作

1、业务库需要存在 undo_log 表

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 COMMENT ='AT transaction mode undo table';

2、业务表主键

业务表中必须包含单列主键,如果存在多列主键,则目前只有mysql支持。

3、页面中自动更新时间戳

业务表中最好不要自动更新时间戳,使用手动更新,更新数据,只更新用到的数据。
比如:
表中存在10个字段,当前业务只需要更新3个字段,此时我们更新3个字段即可,不要更新10个字段,如果update_time字段是默认更新的,则使用手动更新。

3、开启数据源代理

1、自动配置数据源代理

seata:
 enabled: true
 # 是否自动开启数据源代理
 enable-auto-data-source-proxy: true
 # 数据源代理模式,使用AT模式
 data-source-proxy-mode: AT

2、手动配置AT模式数据源代理

1、配置文件关闭自动数据源代理

seata:
 # 是否自动开启数据源代理
 enable-auto-data-source-proxy: false

2、配置配置数据源

AT模式下返回的数据源一定需要是 DataSourceProxy

@Bean
   public DataSource dataSourceProxy() {
       // 某一个数据源
       XxxDataSource xxxDataSource = new XxxDataSource();
       // 设置数据源的各种配置属性
       xxxDataSource.setXXX("");
       // 使用 DataSourceProxy 来包装一下
       return new DataSourceProxy(xxxDataSource);
   }

4、传递 xid

在引入了 spring-cloud-starter-alibaba-seata 后,很多都已经实现了自动传递 xid 。同时在分布式事务结束后,需要清除xid的值。

默认实现了 feignrestweb3种方式的 xid的传递。

springcloud整合seata的实现代码

5、事务分组和seata server对应上

springcloud整合seata的实现代码

6、注册中心和配置中心

应用程序中 seata 的配置中心和 注册中心 需要和 seata server 的保持一致。

springcloud整合seata的实现代码

7、业务方法加上@GlobalTransactional 注解

在需要开启分布式事务的方法上加入 @GlobalTransactional 注解,开启分布式事务。

public class BusinessServiceImpl implements BusinessService {
   private final OrderService orderService;
   private final AccountClient accountClient;
   @Override
   // 开启分布式事务
   @GlobalTransactional(rollbackFor = Exception.class)
   public void createAccountOrder(Integer accountId, Long amount, boolean hasException) {
       System.out.println("xid:" + RootContext.getXID());
       // 1、远程扣减账户余额
       remoteDebit(accountId, amount);
       // 2、下订单
       orderService.createOrder(accountId, amount);
       if (hasException) {
           throw new RuntimeException("发生了异常,分布式事物需要会滚");
       }
   }
   private void remoteDebit(Integer accountId, Long amount) {
       String result = accountClient.debit(accountId, amount);
       log.info("远程扣减库存结果:[{}]", result);
   }
}

六、演示

分布式事务发生异常,事务回滚

springcloud整合seata的实现代码

七、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/seata/seata-springcloud-mybatis-plus

八、参考文档

1、新人文档

2、seata常见问题

来源:https://www.cnblogs.com/huan1993/p/15416067.html

标签:springcloud,seata
0
投稿

猜你喜欢

  • IDEA解决src和resource下创建多级目录的操作

    2023-03-24 07:05:37
  • Java IO文件后缀名过滤总结

    2021-09-01 23:36:47
  • Java数组(Array)最全汇总(中篇)

    2022-09-05 06:01:02
  • Java实现文件读取和写入过程解析

    2023-06-28 11:35:36
  • 如何用java程序(JSch)运行远程linux主机上的shell脚本

    2023-11-24 12:35:58
  • java POI解析Excel 之数据转换公用方法(推荐)

    2023-06-10 11:04:53
  • C++实现的O(n)复杂度内查找第K大数算法示例

    2023-06-30 15:51:13
  • MyBatis 如何配置多个别名 typeAliasesPackage

    2021-11-16 06:35:54
  • Java8新特性之默认方法(default)浅析

    2023-10-03 10:41:13
  • Java中JDBC连接数据库详解

    2023-08-10 16:57:18
  • 详解Spring Boot自动装配的方法步骤

    2023-11-18 15:02:18
  • java日期操作工具类(获取指定日期、日期转换、相隔天数)

    2023-11-28 06:42:53
  • springboot整合solr的方法详解

    2023-01-20 17:54:37
  • Java8 CompletableFuture 异步多线程的实现

    2023-07-21 08:07:15
  • Java编码摘要算法实例解析

    2022-07-21 23:33:29
  • SpringMVC接收多个对象的4种方法

    2023-11-23 06:24:18
  • SpringBoot集成Swagger2的方法

    2023-11-26 13:15:42
  • java开发工作中对InheritableThreadLocal使用思考

    2023-11-24 21:46:44
  • JavaWeb开发基于ssm的校园服务系统(实例详解)

    2022-11-07 16:40:48
  • Hashmap非线程安全关于hash值冲突处理

    2023-11-11 09:22:10
  • asp之家 软件编程 m.aspxhome.com