1. Seata配置Demo实战指南
分布式事务一直是微服务架构中的痛点问题,而Seata作为阿里开源的分布式事务解决方案,凭借其AT模式的无侵入特性,成为众多企业的首选方案。今天我们就来手把手搭建一个完整的Seata配置Demo,从环境准备到事务测试全覆盖。
提示:本文基于Seata 1.5.2版本,适用于Spring Boot 2.3+项目。实际配置时请根据具体版本调整参数。
1.1 环境准备清单
在开始前需要确保以下组件就绪:
- JDK 1.8+(推荐OpenJDK 11)
- MySQL 5.7+(事务日志需要InnoDB引擎)
- Nacos 1.4.2+(作为配置中心和注册中心)
- Seata Server 1.5.2
- Spring Boot 2.3.7.RELEASE
- MyBatis-Plus 3.4.0
建议使用Docker快速搭建基础设施:
# 启动MySQL docker run -p 3306:3306 --name mysql57 \ -e MYSQL_ROOT_PASSWORD=123456 \ -d mysql:5.7 --character-set-server=utf8mb4 # 启动Nacos docker run -p 8848:8848 --name nacos \ -e MODE=standalone \ -d nacos/nacos-server:1.4.21.2 Seata Server部署
从官网下载Seata Server压缩包后,关键配置修改如下:
- registry.conf- 注册中心配置
registry { type = "nacos" nacos { serverAddr = "localhost:8848" namespace = "" cluster = "default" } } config { type = "nacos" nacos { serverAddr = "localhost:8848" namespace = "" group = "SEATA_GROUP" } }- file.conf- 事务日志存储配置
store { mode = "db" db { datasource = "druid" dbType = "mysql" url = "jdbc:mysql://localhost:3306/seata?useSSL=false" user = "root" password = "123456" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 } }启动命令:
# Linux/Mac sh bin/seata-server.sh -p 8091 -h 0.0.0.0 # Windows bin\seata-server.bat -p 8091 -h 0.0.0.02. Spring Boot项目集成
2.1 依赖配置
在pom.xml中添加关键依赖:
<dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>1.4.2</version> </dependency>2.2 核心配置项
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 registry: type: nacos nacos: server-addr: localhost:8848 namespace: "" group: "SEATA_GROUP" config: type: nacos nacos: server-addr: localhost:8848 namespace: "" group: "SEATA_GROUP"2.3 数据源代理配置
必须对数据源进行代理才能实现AT模式:
@Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DruidDataSource druidDataSource() { return new DruidDataSource(); } @Primary @Bean("dataSource") public DataSource dataSource(DruidDataSource druidDataSource) { return new DataSourceProxy(druidDataSource); } }3. 分布式事务实战
3.1 业务场景设计
模拟电商下单场景:
- 订单服务:创建订单记录
- 库存服务:扣减商品库存
- 账户服务:扣减用户余额
3.2 全局事务开启
在业务入口方法添加@GlobalTransactional注解:
@Service public class OrderServiceImpl implements OrderService { @GlobalTransactional(name = "create-order", rollbackFor = Exception.class) public void createOrder(OrderDTO orderDTO) { // 1. 创建订单 orderMapper.insert(orderDTO); // 2. 扣减库存 storageFeignClient.deduct(orderDTO.getCommodityCode(), orderDTO.getCount()); // 3. 扣减余额 accountFeignClient.debit(orderDTO.getUserId(), orderDTO.getMoney()); } }3.3 事务回滚测试
故意在账户服务中抛出异常:
@Service public class AccountServiceImpl implements AccountService { public void debit(String userId, BigDecimal money) { // 模拟余额不足 if (money.compareTo(new BigDecimal("1000")) > 0) { throw new RuntimeException("余额不足"); } accountMapper.decrease(userId, money); } }此时观察日志可以看到:
[INFO] i.s.s.i.o.d.DefaultCoordinator:392 - Begin new global transaction [ERROR] i.s.s.i.o.d.DefaultCoordinator:156 - [192.168.1.100:8091:2037568324] commit failed [INFO] i.s.s.i.o.d.DefaultCoordinator:178 - [192.168.1.100:8091:2037568324] rollback process begin4. 关键问题排查指南
4.1 常见启动问题
问题1:Could not get available server
解决方案:
- 检查nacos控制台是否注册成功
- 确认tx-service-group与vgroup-mapping匹配
- 查看seata-server启动日志是否有异常
问题2:Branch session rollback failed
解决方案:
- 检查undo_log表是否创建
- 确认数据源代理配置正确
- 验证MySQL账户是否有足够权限
4.2 性能优化建议
- 客户端配置优化:
seata: client: rm: report-retry-count: 5 async-commit-buffer-limit: 10000 tm: commit-retry-count: 5 rollback-retry-count: 5- Server端JVM参数:
-server -Xmx2048m -Xms2048m -XX:MaxDirectMemorySize=1024m4.3 监控配置
建议开启Seata的Metrics监控:
seata: metrics: enabled: true registry-type: compact exporter-list: prometheus exporter-prometheus-port: 9898配合Grafana可以可视化监控事务数据:
http://localhost:9898/metrics5. 生产环境注意事项
- 高可用部署:
- Seata Server集群部署(至少3节点)
- 数据库主从配置
- Nacos集群部署
- 事务日志清理:
-- 定期清理已完成的事务日志 DELETE FROM undo_log WHERE log_created < DATE_SUB(NOW(), INTERVAL 7 DAY);- 异常处理建议:
@GlobalTransactional public void businessMethod() { try { // 业务代码 } catch (Exception e) { // 手动标记回滚 GlobalTransactionContext.reload(RootContext.getXID()).rollback(); throw e; } }在实际项目中,我们发现当并发量超过500TPS时,建议:
- 调整seata.server.session.branch.async.queue.size(默认10000)
- 优化undo_log表的索引(添加xid索引)
- 使用Redis作为分布式锁存储(替代默认的file模式)