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.1

application.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 做服务注册与配置中心

Spring Cloud 实战