springcloud2.1.0整合seata1.5.2+nacos2.10(附源码)
1.创建springboot2.2.2+springcloud2.1.0的maven父子工程如下,不过多描述:
搭建过程中也出现很多问题,主要包括:
1.seataServer.properties配置文件的组一定要在SEATA_GROUP下
2.配置seata yml配置文件要拷贝仔细
3.事务组cluster: xuewei_tx_group服务端和客户端yml里要对应xuewei_tx_group
2.主要的配置文件如下
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xuewei</groupId>
<artifactId>springcloud-seata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-seata</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2021.1</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.5.2</version>
</dependency>
<!-- 以 nacos 做服务配置中心的依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<!--feign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.xuewei</groupId>
<artifactId>springcloud-common</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version><!--$NO-MVN-MAN-VER$ -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<!--默认情况下是true 现在修改为false 就不会过滤掉这个xml文件了-->
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.yml</include>
<include>*.conf</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
springboot配置文件bootstrap.yml
server:
port: 8080
spring:
profiles:
active: dev
application:
name: seata
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.167.0.125:3306/xuewei?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: lnats@WeaVer
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
logging:
level:
io:
seata: info
seata:
tx-service-group: xuewei_tx_group #这里每个服务都是对应不同的映射名,在配置中心可以看到
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
application: seata-server
service:
vgroup-mapping:
#这里也要注意 key为映射名
xuewei_tx_group: xuewei_tx_group
注意:每个moudle中都要加,是由seata机制决定
seata:
tx-service-group: xuewei_tx_group #这里每个服务都是对应不同的映射名,在配置中心可以看到
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
application: seata-server
service:
vgroup-mapping:
#这里也要注意 key为映射名
xuewei_tx_group: xuewei_tx_group
3.seata原理如下图:
处理过程
TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID;
XID在微服务调用链路的上下文中传播;
RM向TC注册分支事务,将其纳入XID对应全局事务的管辖;
TM向TC发起针对XID的全局提交或回滚决议;
TC调度XID下管辖的全部分支事务完成提交或回滚请求。
4,演示seata全局事务场景
5.启动所有的moudle
启动成功并成功链接seata后会提示
nacos配置中心如下图:
6.还有比较重要的,在每个业务数据库都需要建各自的回滚日志表undo_log表
脚本如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `undo_log`
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AT transaction mode undo table';
-- ----------------------------
-- Records of undo_log
-- ----------------------------
7.测试seata效果:
首选不加全局事务标签@GlobalTransactional的情况访问接口http://localhost:8080/test/add
我们会发现数据库情况,两个模块其中之一入库了
当我们开启事务标签后,首先清空数据库
然后再执行方法
然后我们刷新数据库,这从user表数据回滚了,seata生效了
8.源码分享如下:
gitee:https://gitee.com/zhangxuewei/springcloud-sentinel-seata.git
数据库脚本在db中