Seata
Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的分布式事务解决方案,解决微服务架构下跨服务、跨数据库的事务一致性问题。
核心角色
业务服务(TM 发起全局事务)
│
▼
TC(Transaction Coordinator)— Seata Server
负责:全局事务的注册、提交、回滚协调
│
├── 服务 A(RM,操作数据库 A)
├── 服务 B(RM,操作数据库 B)
└── 服务 C(RM,操作数据库 C)
| 角色 | 说明 |
|---|---|
| TC(Transaction Coordinator) | Seata Server,协调全局事务的提交/回滚 |
| TM(Transaction Manager) | 事务发起方,定义全局事务边界(@GlobalTransactional) |
| RM(Resource Manager) | 事务参与方,管理本地资源,向 TC 注册分支事务 |
事务模式
AT 模式(自动补偿,推荐)
框架自动解析 SQL,生成 undo_log 记录回滚镜像,无需业务手动写补偿逻辑。
一阶段:执行业务 SQL + 记录 undo_log,锁定行
二阶段提交:删除 undo_log,释放锁
二阶段回滚:根据 undo_log 还原数据,释放锁
每个参与方数据库需建 undo_log 表:
CREATE TABLE `undo_log` (
`branch_id` BIGINT NOT NULL,
`xid` VARCHAR(128) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
PRIMARY KEY (`branch_id`),
KEY `ix_log_created` (`log_created`)
) ENGINE=InnoDB;TCC 模式(手动补偿)
需业务实现三个接口,适合高性能或非关系型数据库场景:
@LocalTCC
public interface StockService {
@TwoPhaseBusinessAction(name = "deductStock",
commitMethod = "commit", rollbackMethod = "rollback")
boolean prepare(BusinessActionContext ctx,
@BusinessActionContextParameter("productId") Long productId);
boolean commit(BusinessActionContext ctx);
boolean rollback(BusinessActionContext ctx);
}SAGA 模式
适合长事务,每个步骤有对应补偿操作,通过状态机编排:
正向:A → B → C
补偿:C补偿 → B补偿 → A补偿
XA 模式
基于数据库 XA 协议,强一致性,持有数据库锁直到全局事务结束,性能最低。
事务模式对比
| 模式 | 侵入性 | 性能 | 一致性 | 适用场景 |
|---|---|---|---|---|
| AT | 低(自动) | 高 | 最终一致 | 关系型数据库,大多数场景 |
| TCC | 高(手动三接口) | 最高 | 最终一致 | 高性能,非关系型资源 |
| SAGA | 中(编排补偿) | 高 | 最终一致 | 长事务,异构系统 |
| XA | 低 | 低 | 强一致 | 强一致要求,性能不敏感 |
Spring Boot 集成(AT 模式)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2022.0.0.0</version>
</dependency>seata:
enabled: true
application-id: order-service
tx-service-group: my_tx_group
service:
vgroup-mapping:
my_tx_group: default
registry:
type: nacos
nacos:
server-addr: localhost:8848
group: SEATA_GROUP@Service
public class OrderService {
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public void createOrder(Long userId, Long productId, int count) {
storageService.deduct(productId, count); // 扣减库存
orderRepository.save(new Order(userId, productId, count));
accountService.deduct(userId, count * PRICE); // 扣减余额
// 任意一步抛异常,全局事务自动回滚
}
}Seata Server 部署
# 启动(生产建议 store.mode=db,事务日志存 MySQL)
sh bin/seata-server.sh -p 8091 -h 127.0.0.1application.yml 关键配置:
seata:
store:
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/seata
user: seata
password: seata注意事项
- AT 模式每个参与方数据库都需要建
undo_log表 - 全局事务范围内避免长事务(会长时间持有全局锁)
@GlobalTransactional只需加在 TM 发起方,参与方不需要加- 跨服务调用通过 Feign/Dubbo,Seata 自动传播
xid
相关链接
- Zookeeper — Seata HA 模式可用 ZooKeeper 做注册中心
- ShardingSphere — 分库分表场景下可集成 Seata 处理跨库事务
- Nacos — Seata Server 常用 Nacos 做服务注册与配置中心