SpringBoot集成Seata分布式事务OpenFeign远程调用

本文主要是介绍SpringBoot集成Seata分布式事务OpenFeign远程调用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Docker Desktop 安装Seata Server

seata 本质上是一个服务,用docker安装更方便,配置默认:file

docker run -d --name seata-server -p 8091:8091 -p 7091:7091 seataio/seata-server:2.0.0

与SpringBoot集成

表结构

在这里插入图片描述

项目目录

在这里插入图片描述

dynamic和dynamic2新建user、undo_log表

每个数据库都必须包含undo_log表(user表不是必须的,这里只是演示

CREATE TABLE `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 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`),KEY `ix_log_created` (`log_created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AT transaction mode undo table';

spring-boot-feign-seata1

pom.xml

		<!-- lombok 1.18.26 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope><optional>true</optional></dependency><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- mysql 8.0.32 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version><scope>runtime</scope></dependency><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- web 2.7.9 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatis-Plus 3.5.2 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- seata 调用方用 openfeign 必须引入spring-cloud-starter-alibaba-seata,否则被调用方获取到的xid可能会为null --><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></dependency><!-- cloud seata 2.0.0 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions></dependency><!-- openfeign 3.1.9 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

application.yml

server:port: 8088spring:application:name: spring-boot-feign-seata1datasource:driver-class-name: com.mysql.cj.jdbc.Driver# 数据库必须包含 undo_log 表,如果没有则用 resources 目录下的undo_log.sql 创建url: jdbc:mysql://127.0.0.1:3306/dynamic?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456seata:tx-service-group: my_test_tx_group

SpringBootFeignSeata1Application.java

@MapperScan
@EnableFeignClients
// seata 版本兼容性问题,如果启动报错就要排除 SeataRestTemplateAutoConfiguration 自动配置
@SpringBootApplication(exclude = SeataRestTemplateAutoConfiguration.class)
public class SpringBootFeignSeata1Application {public static void main(String[] args) {SpringApplication.run(SpringBootFeignSeata1Application.class, args);}}

User.java

@Data
@TableName("user")
public class User {@TableId(type = IdType.AUTO)private Integer id;private String name;
}

UserMapper.java

public interface UserMapper extends BaseMapper<User> {}

UserController.java

@RestController
@RequiredArgsConstructor
public class UserController {private final UserService userService;@GetMapping("user")public String user(@RequestParam(name = "rollback") boolean rollback) {User user = new User();user.setName("Meta");try {userService.insert(rollback, user);} catch (Exception e) {return "rollback";}return "success";}}

UserFeignClient.java(openfeign调用spring-boot-feign-seata2)

@FeignClient(name = "spring-boot-feign-seata2", url = "127.0.0.1:8089")
public interface UserFeignClient {@GetMapping("user")void user();}

UserService.java(主要的)

@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {private final UserMapper userMapper;private final UserFeignClient userFeignClient;/*** 全局事务* 1、pom.xml引入seata-spring-boot-starter* 2、pom.xml引入spring-cloud-starter-alibaba-seata(排除:seata-spring-boot-starter,因为前面已经引入了。)* 3、使用 @GlobalTransactional 全局事务注解开启全局事务控制(默认:Seata AT 模式)* 4、被调用方业务层需要引入 @Transactional 本地事务注解*/@GlobalTransactional(rollbackFor = Exception.class)public void insert(boolean rollback, User user) {log.info("seata1 xid = {}", RootContext.getXID());userMapper.insert(user);userFeignClient.user();if (rollback) {throw new RuntimeException("rollback");}}
}

spring-boot-feign-seata2

pom.xml和spring-boot-feign-seata是一样的

application.yml

server:port: 8089spring:application:name: spring-boot-feign-seata2datasource:driver-class-name: com.mysql.cj.jdbc.Driver# 数据库必须包含 undo_log 表,如果没有则用 resources 目录下的undo_log.sql 创建url: jdbc:mysql://127.0.0.1:3306/dynamic2?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456seata:tx-service-group: my_test_tx_group

SpringBootFeignSeata2Application.java

@MapperScan
// 被调用端引用 seata 默认 AT 模式
@EnableAutoDataSourceProxy
// seata 版本兼容性问题,如果启动报错就要排除 SeataRestTemplateAutoConfiguration 自动配置
@SpringBootApplication(exclude = SeataRestTemplateAutoConfiguration.class)
public class SpringBootFeignSeata2Application {public static void main(String[] args) {SpringApplication.run(SpringBootFeignSeata2Application.class, args);}}

UserController.java

@RestController
@RequiredArgsConstructor
public class UserController {private final UserService userService;@GetMapping("user")public void user() {User user = new User();user.setName("Meta2");userService.insert(user);}}

UserService.java

@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {private final UserMapper userMapper;/*** 调用方用 openfeign 必须引入spring-cloud-starter-alibaba-seata,否则被调用方获取到的xid可能会为null* PS:被调用方可以不用引入*/@Transactional(rollbackFor = Exception.class)public void insert(User user) {log.info("seata2 xid = {}", RootContext.getXID());userMapper.insert(user);}}

上面重复的文件就不说了

启动两个项目

访问localhost:8088/user?rollback=true

返回rollback,2个数据库都没有新增数据库,验证分布式(AT)事务回滚成功

访问localhost:8088/user?rollback=false

返回success,2个数据库都新增了数据,验证分布式(AT)事务成功

这篇关于SpringBoot集成Seata分布式事务OpenFeign远程调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/988827

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("