这篇中我们就要项目实战中来使用 Seata 了,毕竟学习它就是为了实战中使用的。
其实 Seata 使用起来很简单,主要就是使用 @GlobalTransactional注解,但是搭建过程却还是稍微有点复杂的。
话不多说,开始今天的学习。
一、前言
- 本案例使用的是
Seata的 AT 模式 - 由于篇幅有限,本文只贴出核心代码和配置,完整代码地址:cloud-seata: seata demo - Gitee.com
- 本案例使用 Nacos 作为注册中心,使用 Nacos 作为配置中心
1. 版本说明
MySQL 8.0.27Nacos Server 2.0.3Seata Server 1.4.2Spring Boot 2.3.7.RELEASESpring Cloud Hoxton.SR9Spring Cloud Alibaba 2.2.5.RELEASE
2. 案例目标
本案例将会创建三个服务,分别是订单服务、库存服务、账户服务,各服务之间的调用流程如下:
- 1)当用户下单时,调用订单服务创建一个订单,然后通过远程调用(OpenFeign)让库存服务扣减下单商品的库存
- 2)订单服务再通过远程调用(OpenFeign)让账户服务来扣减用户账户里面的余额
- 3)最后在订单服务中修改订单状态为已完成
上述操作跨越了三个数据库,有两次远程调用,很明显会有分布式事务的问题,项目的整体结构如下:
cloud-seata
├── seata-account # 账户模块,端口:9201
├── seata-order # 订单模块,端口:9211
└── seata-product # 库存模块,端口:9221
复制代码
二、代码
1. 账户服务搭建
创建 seata-account 服务模块

1.1、创建数据库
# 账户数据库信息 seata_account
DROP DATABASE IF EXISTS seata_account;
CREATE DATABASE seata_account;
DROP TABLE IF EXISTS seata_account.account;
CREATE TABLE seata_account.account
(
id INT(11) NOT NULL AUTO_INCREMENT,
balance DOUBLE DEFAULT NULL,
last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4;
DROP TABLE IF EXISTS seata_account.undo_log;
CREATE TABLE seata_account.undo_log
(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
branch_id BIGINT(20) NOT NULL,
xid VARCHAR(100) NOT NULL,
context VARCHAR(128) NOT NULL,
rollback_info LONGBLOB NOT NULL,
log_status INT(11) NOT NULL,
log_created DATETIME NOT NULL,
log_modified DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY ux_undo_log (xid, branch_id)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4;
INSERT INTO seata_account.account (id, balance)
VALUES (1, 50);
复制代码
其中,库中的undo_log表,是Seata AT模式必须创建的表,主要用于分支事务的回滚。 另外,考虑到测试方便,我们插入了一条id = 1的account记录。
1.2、添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
复制代码
由于使用的SpringCloud Alibaba依赖版本是2.2.5.RELEASE,其中自带的 seata 版本是1.3.0,但是我们 Seata 服务端使用的版本是 1.4.2,因此需要排除原有的依赖,重新添加 1.4.2 的依赖。
如果依赖版本不一致,启动后会报如下错误
no available service 'null' found, please make sure registry config correct

注意:seata 客户端的依赖版本必须要和服务端一致。
1.3、服务配置文件
server:
port: 9201
# spring配置
spring:
application:
name: seata-account
datasource:
druid:
username: r

本文详细介绍了如何在实际项目中使用Seata进行分布式事务管理。通过创建订单、库存和账户三个服务,展示了在Spring Cloud Alibaba框架下,如何利用Seata的AT模式解决跨数据库和远程调用的事务问题。文章包含每个服务的搭建步骤、核心代码展示以及各种场景的测试,包括正常下单、库存不足和用户余额不足的情况。
最低0.47元/天 解锁文章
947

被折叠的 条评论
为什么被折叠?



