什么是Seata?

重点

Seata是阿里开源的分布式事务简介方案,专门解决微服务场景下跨服务、跨数据库的数据一致性问题。
分布式事务的难点在于,一个业务操作可能设计多个服务、多个数据库,每个服务本地事务能保证ACID,但整体业务的原子性没人管。
比如下单扣库存,订单服务写成功了,库存服务挂了,数据就乱了。Seata就是来解决这个问题的。
Seata有三个核心角色:

  1. TC,事务协调者,独立部署服务器。它维护全局事务和分支事务的状态,负责协调各个分支是提交还是回滚。可以理解为一个总指挥。
  2. TM, 事务管理者,嵌入在业务应用里。它负责开启全局事务、提交或回滚全局事务。加了@GlobalTransactionl注解的方法,TM就会在方法开始时往TC注册一个全局事务
  3. RM,资源管理器,也嵌入在业务应用内。它负责管理分布事务,向TC注册分支,报告分支状态,执行TC下的提交或回滚指令,每个参与分布式事务的数据源都有一个RM。

整个流程是:TM开启全局事务,业务代码调用各个微服务,每个服务的RM注册分支事务并执行本地SQL,所有分支执行完毕后,TM通知TC全局提交或回滚,TC再通知各个RM执行相应操作。

扩展

为什么需要分布式事务

单体应用时代,一个数据库,本地事务就能搞定一切。Spring的@Transactional一加,要么全成功要么全回滚,干净利落。
微服务拆分之后,情况就复杂了。一个业务操作拆成多个微服务调用,每个服务都有自己的数据库。订单服务、库存服务、账户服务各管各的,本地事务只能保证自己那一亩三分地,整体一致性没人管。

经典场景:用户下单,需要创建订单、扣减库存、扣减余额。订单创建成功了,库存扣了,扣余额的时候账户服务挂了。没有分布式事务的话,订单和库存都回滚不了,数据就脏了。

Seata的事务模式

Seata提供了四种事务模式,适用于不同场景:

模式 原理 侵入性 性能 使用场景
AT 自动生成回滚SQL 低、只需注解 大多数场景
TCC 业务代码实现try/confirm/cancel 最高 高并发、强一致性
Saga 正向服务+补偿服务 长事务、跨公司
XA 数据库原生XA协议 传统数据迁移

AT模式工作原理

AT模式是两阶段提交的变种,理解它的关键是undo_log。
一阶段:业务SQL执行前,RM解析SQL拿到表名、主键、修改前后的数据镜像,把这些信息存到undo_log表,然后执行业务SQL,本地事务直接提交。注意这里本地食物就提交了,不像XA那样一致持有锁。

-- 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 idx_xid (xid)
);

二阶段提交:如果所有分支都成功,TC通知各RM删除undo_log就完事了,异步执行很快。
二阶段回滚:如果有分支失败,TC通知各RM回滚。RM根据undo_log里的数据镜像生成反向SQL,比如UPDATE变成还原旧值的UPDATE,INSERT变成DELETE,DELETE变成INSERT。

全局锁与写隔离

AT模式一阶段就提交本地事务了,那怎么防止脏写?答案是全居所。
执行业务SQL之前,RM会向TC申请全局锁,锁的粒度是“表名”+“主键”。如果另一个全局事务想修改同一个数据,必须等锁释放。本地事务可以不受全局锁影响,所以Seata默认只能保证“写隔离”,读隔离需要@GlobalLock+SELECT FOR UPDATE。

@GlobalTransactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
    // 执行前会申请 account 表 fromId 和 toId 的全局锁
    accountService.deduct(fromId, amount);
    accountService.increase(toId, amount);
}

TC集群部署

生产环境TC必须高可用,Seata支持多种注册中心:Nacos、Eureka、Consul、ZooKeeper。事务日志可以存到数据库或Redis。
一般配置2-3个TC节点,通过Nacos做服务开发和配置管理。压测时关注TC的吞吐量,单节点大概能扛住每秒1万左右的分支事务。如果并发更高,可以通过事务分组把不同业务的事务路由到不同的TC集群。

Seata与其他方案对比

分布式事务方案不止Seata一种,选型时要考虑场景:

方案 优点 缺点 使用场景
Seata AT 侵入低、接入快 需要undo_log 内部微服务
本地消息表 实现简单、可靠 消息延迟 最终一致性
RocketMQ 事务消息 性能低 依赖MQ 消息驱动场景
手写TCC 性能最优 开发成本高 核心交易链路

大厂一般混合使用:核心交易链路用TCC,普通业务用Seata AT,非核心流程用消息最终一致性。别一上来就用Seata,先评估业务对一致性的要求,很多场景最终一致性就够了。

posted @ 2026-04-17 13:15  生活的样子就该是那样  阅读(18)  评论(0)    收藏  举报