概述
在微服务中每个服务都是对应的自己的db,相对应的事务也是各管各的。那么在某些场景下自然就要分布式的事务管理,比如下单扣库存场景。
环境
java 1.8
seata 1.4.2
nacos 1.4.1
springboot 2.7.4
先准备好db中的表
CREATE TABLE `t_order` (
`id` int NOT NULL AUTO_INCREMENT,
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`commodity_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`count` int DEFAULT '0',
`amount` double(14,2) DEFAULT '0.00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `t_stock` (
`id` int NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`count` int DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `commodity_code` (`commodity_code`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'increment id',
`branch_id` bigint NOT NULL COMMENT 'branch transaction id',
`xid` varchar(100) 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 NOT NULL COMMENT 'create datetime',
`log_modified` datetime NOT NULL COMMENT 'modify datetime',
`ext` varchar(100) DEFAULT NULL COMMENT 'reserved field',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='AT transaction mode undo table';
项目结构
依赖情况
父依赖
<?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.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fchan</groupId>
<artifactId>tcc_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tcc_demo</name>
<packaging>pom</packaging>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<modules>
<module>account</module>
<module>order</module>
<module>stock</module>
<module>common</module>
</modules>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
公共依赖
<?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>
<artifactId>tcc_demo</artifactId>
<groupId>com.fchan</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.fchan</groupId>
<artifactId>tcc_seata_common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2021.0.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
订单服务依赖
<?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>
<artifactId>tcc_demo</artifactId>
<groupId>com.fchan</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.fchan</groupId>
<artifactId>order</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fchan</groupId>
<artifactId>tcc_seata_common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
库存服务依赖
<?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>
<artifactId>tcc_demo</artifactId>
<groupId>com.fchan</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.fchan</groupId>
<artifactId>stock</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>stock</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>com.fchan</groupId>
<artifactId>tcc_seata_common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml配置参数
订单服务
server:
port: 9011
# seata配置
seata:
# 默认关闭,如需启用spring.datasource.dynami.seata需要同时开启
enabled: true
# Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name}
# Seata 事务组编号,用于 TC 集群名
tx-service-group: default_tx_group
# 关闭自动代理
enable-auto-data-source-proxy: true
# 服务配置项
service:
# 虚拟组和分组的映射
vgroup-mapping:
default_tx_group: default
config:
type: nacos
nacos:
serverAddr: xxx.xxx.xxx.xxx:8848
group: SEATA_GROUP
namespace: ""
username: nacos
password: nacos
data-id: "seataServer.properties"
registry:
type: nacos
nacos:
application: seata-server
server-addr: xxx.xxx.xxx.xxx:8848
namespace: ""
username: nacos
password: nacos
spring:
application:
name: tccOrder
datasource:
url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/seata_pay?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: mark10086
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
idle-timeout: 100000
maximum-pool-size: 10
max-lifetime: 100000
connection-timeout: 30000
connection-test-query: select 1
validation-timeout: 500
cloud:
nacos:
server-addr: xxx.xxx.xxx.xxx:8848
discovery:
group: SEATA_GROUP
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
库存服务yml配置
server:
port: 9010
# seata配置
seata:
# 默认关闭,如需启用spring.datasource.dynami.seata需要同时开启
enabled: true
# Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name}
# Seata 事务组编号,用于 TC 集群名
tx-service-group: default_tx_group
# 关闭自动代理
enable-auto-data-source-proxy: true
# 服务配置项
service:
# 虚拟组和分组的映射
vgroup-mapping:
default_tx_group: default
config:
type: nacos
nacos:
serverAddr: xxx.xxx.xxx.xxx:8848
group: SEATA_GROUP
namespace: ""
data-id: "seataServer.properties"
username: "nacos"
password: "nacos"
registry:
type: nacos
nacos:
application: seata-server
server-addr: xxx.xxx.xxx.xxx:8848
namespace: ""
group: SEATA_GROUP
username: "nacos"
password: "nacos"
spring:
application:
name: tccStock
datasource:
url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/seata_pay?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: mark10086
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
idle-timeout: 100000
maximum-pool-size: 10
max-lifetime: 100000
connection-timeout: 30000
connection-test-query: select 1
validation-timeout: 500
cloud:
nacos:
server-addr: xxx.xxx.xxx.xxx:8848
discovery:
group: SEATA_GROUP
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
调用流程
订单服务模拟调用
库存服务模拟异常
此时查看下db情况,可以看到订单表中新插入一条数据,库存扣减了50,undolog中有2条记录。然后出发异常的时候会全局回滚。证明seata全局事务生效



版权声明:本文为weixin_43944305原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。