分布式事务解决方案:最佳实践(面向初学者的实战教程)
开篇:你为什么需要分布式事务?

想象这样一个场景:你在网上购物,付款成功后系统提示订单创建失败了。为什么会这样?这可能是因为支付和下单是两个不同的服务,而这两个操作没能同时完成。
这就引出了我们今天要学的内容 —— 分布式事务。它解决的是在多个服务之间保证事务一致性的问题。
通俗点说,就是让你在“转账”、“下单”、“库存扣减”等多个步骤中,要么全部成功,要么全部失败,不会出现一半完成的情况。
环境准备:搭建开发环境

我们要使用 Spring Boot + Seata 来演示分布式事务的实现。Seata 是一个开源的分布式事务解决方案,适合刚入门的学习者。
步骤 1:安装 Java JDK
确保你已安装 JDK 1.8 或以上版本。
java -version
如果没有安装,请去 Oracle官网 下载安装。
步骤 2:安装 MySQL 数据库
你可以通过以下命令安装:
sudo apt update
sudo apt install mysql-server
安装完成后,启动数据库,并新建一个名为 order 的数据库。
CREATE DATABASE order;
同样创建另一个数据库 account 和 storage。
步骤 3:安装并启动 Seata Server
前往 Seata 官网 下载 Seata 的压缩包(建议选稳定版本如 v1.7.0)。
解压后进入目录:
cd seata-server-1.7.0
运行 Seata:
sh ./bin/seata-server.sh
如果你用的是 Windows,可以用 PowerShell 执行 .bat 文件启动。
核心概念:几个必须理解的专业术语

为了更好地理解分布式事务,下面这几个术语非常重要:
| 术语 | 解释 |
|---|---|
| TC(Transaction Coordinator) | 事务协调器,也就是 Seata Server,负责协调全局事务 |
| TM(Transaction Manager) | 事务管理器,用于开启和提交/回滚全局事务 |
| RM(Resource Manager) | 资源管理器,每个微服务就是一个 RM |
简单类比一下:
- TC 就像裁判;
- TM 是队长,负责发起比赛(事务);
- RM 是球员,负责执行具体动作(操作数据库)。
实战项目:实现一个简单的电商系统
我们将实现一个电商系统的三个核心服务:
- 库存服务(Storage)
- 订单服务(Order)
- 账户服务(Account)
这三个服务各自有数据库,我们要让它们一起完成一个事务:下单 → 扣库存 → 扣余额,如果任何一个失败,整个操作都要回滚。
第一步:创建 Spring Boot 项目结构
你可以使用 Spring Initializr 创建项目,选择如下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
然后创建三个模块:
- storage-service(库存服务)
- order-service(订单服务)
- account-service(账户服务)
第二步:引入 Seata 依赖
在每个服务的 pom.xml 中添加:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
第三步:配置 Seata 连接信息
在每个服务的 application.yml 添加如下内容:
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: my_test_tx_group
service:
vgroup-mapping:
my_test_tx_group: default
grouplist:
default: 127.0.0.1:8091
这里的 grouplist 指向你本地运行的 Seata Server 地址,默认端口为 8091。
第四步:写一个下单接口(以 Order Service 为例)
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/create")
public String createOrder() {
try {
orderService.create();
return "订单创建成功";
} catch (Exception e) {
return "订单创建失败:" + e.getMessage();
}
}
}
第五步:编写带有事务注解的服务方法
@Service
public class OrderService {
@Autowired
private StorageClient storageClient;
@Autowired
private AccountClient accountClient;
@GlobalTransactional // 关键:启用全局事务
public void create() {
// 1. 创建订单
System.out.println("开始创建订单...");
// 2. 扣库存
storageClient.decrease(1L, 2);
// 3. 扣余额
accountClient.decrease(1L, 50);
if (Math.random() > 0.5) {
throw new RuntimeException("模拟异常");
}
}
}
注意:我们在代码最后加了一个随机抛异常逻辑,用来测试是否支持回滚。
第六步:其他服务也需要对应的客户端方法
比如 StorageClient 是通过 Feign 调用 Storage Service 提供的接口:
@FeignClient(name = "storage-service")
public interface StorageClient {
@PostMapping("/decrease")
void decrease(@RequestParam Long productId, @RequestParam Integer count);
}
对应的 Storage Service 里有一个实际操作数据库的接口。
常见问题解答
❓ Q1:分布式事务会影响性能吗?
A:会有一点影响,因为多了一层事务控制和日志记录。但如果业务需求确实需要强一致性,这是值得的。
❓ Q2:Seata 支持哪些数据库?
A:主流的数据库都支持,如 MySQL、PostgreSQL、Oracle 等。 使用时只需加上 AT 模式的自动代理即可。
❓ Q3:能否在不改代码的前提下使用 Seata?
A:不能完全无侵入,至少要在主入口加 Seata 配置,并在业务方法上加 @GlobalTransactional 注解。
❓ Q4:除了 Seata,还有哪些常见的分布式事务框架?
A:常见方案包括:
- TCC(Try-Confirm-Cancel)
- SAGA(事件驱动型)
- 两阶段提交(2PC)—— 不推荐用于生产
- 消息队列+本地事务表(适用于最终一致性)
学习建议:下一步怎么走?
掌握了 Seata 的基本使用之后,你就可以进一步深入学习以下内容:
✅ 推荐学习路径:
- 学习更多分布式事务模式
- 如 TCC、SAGA、Event Sourcing 等
- 了解 Seata 源码实现原理
- 有助于深入理解事务协调机制
- 结合消息队列使用
- 比如 RabbitMQ 或 Kafka,提高异步处理能力
- 部署到真实环境中练习
- 比如阿里云 ECS + 容器化部署
总结
本篇文章带大家从零基础了解什么是分布式事务,以及如何使用 Seata 在 Spring Boot 项目中实现它。通过实战项目,我们实现了下单流程中的三个关键操作,并验证了其事务一致性。
作为初学者,记住一句话:
“先跑通,再深入。”
希望这篇图文并茂的小白友好教程能帮助你快速上手分布式事务!
💡 小贴士:遇到问题不要怕,多查 Seata 的 GitHub Issues 和官方文档,你会发现里面有很多答案等着你!

评论 0