seata

Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。

seata服务器的web界面的端口是7091,而8091是TC协调者的TCP端口

Seata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成:

  1. seata有服务器端和客户端,客户端要连上服务器才能使用。
  2. TC(Transaction Coordinator,事务协调者)在服务器端的官网下载: 全局事务的管理者。用于维护全局和分支事务的状态,驱动TM的全局提交和回滚。TM和RM通过TC注册分支和汇报状态。
  3. TM(Transaction Manager,事务管理器)在客户端:发起全局事务,定义全局事务的范围,操作全局事务的提交和回滚。
  4. RM(Resources Manager,资源管理器)在客户端:操作自己分支的事务提交和回滚

注意:seata的稳定性非常重要,如果TC崩了,那所有的事务管控都失效。

环境配置

参考官方 | 快速开始

  1. 下载地址:官网GitHub。这里使用的官网下载的包。
  2. 创建seta的AT模式使用的数据表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  1. 解压并启动:seata-server.bat 访问:http://localhost:7091/ 账号密码都是seata
  2. 在微服务中导入spring-cloud-starter-alibaba-seata依赖
  3. 在resources里建file.conf文件,每个seata服务都配置:
1
2
3
4
5
6
7
8
9
10
service {
#transaction service group mapping
vgroupMapping.default_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
default.grouplist = "127.0.0.1:8091"
#degrade, current not support
enableDegrade = false
#disable seata
disableGlobalTransaction = false
}
  1. 在RM分支事务微服务中启动类上加入@EnableTransactionManagement,在具体事务service方法上加@Transactional
  2. 在TM全局事务微服务中启动类上不加@EnableTransactionManagement,但在事务service方法上要加上@GlobalTransactional。这个注解是核心

测试本地事务

  1. 没有@EnableTransactionManagement@Transactional两注解;不会触发回滚。
  2. @Transactional,但没有@EnableTransactionManagement;会产生一个问题:没有@EnableTransactionManagement,异常数据也能回滚,为什么?
  • 在 Spring Boot 中,不需要 @EnableTransactionManagement 也能回滚数据,因为 Spring Boot 默认开启了事务管理。
  • 如果你在 Spring 传统项目里,可能就需要手动启用事务管理。所以还是启动类加上@EnableTransactionManagement
  1. @EnableTransactionManagement@Transactional两注解
  • 单个本地事务是有效的,但是有远程调用时,本地异常回滚了,远程调用却成功了。
  • 这就导致了分布式事务用这两个注解不管用,怎么办?去掉本地启动类的@EnableTransactionManagement,将本地方法的@Transactional改成@GlobalTransactional

springboot默认开启事务

测试分布式事务

模拟情景:采购服务要远程调用 扣库存和下订单服务,订单服务又要远程调用扣减余额服务,怎么保证分布式事务的数据一致性?

操作:

  1. 先在各个模块启动类上加入@EnableTransactionManagement,全局事务(采购模块)除外。
  2. 各分支事务加@Transactional,全局事务加@GlobalTransactional

seata各模式原理

区分狭义事务和广义事务

狭义事务:数据库的操作

广义事务:业务的事务(包括数据库操作),举例:事务中需要发邮件和发短信,这种不能撤回的情况,AT和XA模式不管用了。

AT模式

📌 本质:自动两阶段提交 + undo log 回滚
🎯 特点:无侵入、自动补偿、最终一致性
🔑 核心:全局锁(防脏写)+ undo_log(防丢数据)

工作原理(两阶段提交):
一阶段:业务SQL执行 → 记录前后镜像 → 插入undo_log → 申请全局锁→ 提交本地事务 → 释放本地锁
二阶段:

  • 全成功 → 异步删undo_log,释放全局锁
  • 有失败 → 根据undo_log反向补偿回滚,释放全局锁

⚠️ 适合:传统单体改微服务、CRUD为主、读多写少
⚠️ 不适合:高并发热点数据、复杂SQL、要求强一致性

参考

https://www.cnblogs.com/cjsblog/p/16848782.html
https://blog.csdn.net/qq_42767920/article/details/135743126