Seata事务框架

166 阅读4分钟

Seata(Simple Extensible Autonomous Transaction Architecture) 是阿里巴巴开源的分布式事务解决方案,支持 AT(自动补偿)TCC(手动补偿)Saga(长事务)XA(强一致) 四种模式,适用于不同业务场景。

一、Seata 核心组件

组件角色
TC(Transaction Coordinator)事务协调器,独立部署,负责全局事务的提交/回滚协调。
TM(Transaction Manager)事务管理器,嵌入应用,负责定义事务边界(如 @GlobalTransactional)。
RM(Resource Manager)资源管理器,管理分支事务(如数据库连接),向 TC 注册分支事务状态。

二、Seata 事务模式对比

模式原理优点缺点适用场景
AT基于 SQL 解析自动生成回滚日志,实现两阶段提交。无侵入,适合大部分场景。依赖数据库本地事务,全局锁可能影响性能。普通业务(如订单创建)
TCC手动编写 Try/Confirm/Cancel 接口,通过业务补偿实现最终一致性。无资源锁定,高性能。代码侵入性强,需处理悬挂和空回滚。高并发短事务(如秒杀)
Saga通过正向操作与逆向补偿操作链实现长事务。适合跨服务长流程。需保证补偿幂等性,数据不一致窗口较长。旅行预订、电商订单
XA基于数据库 XA 协议,实现强一致性。强一致性,传统应用兼容性好。性能低,资源锁定时间长。传统数据库应用

三、AT 模式实现原理

1. 执行流程

TM(应用)TC(Seata Server)RM(数据库)1. 开启全局事务(XID=1232. 执行SQL(生成前镜像+后镜像,写入undo_log)3. 注册分支事务(XID=123, Branch ID=14. 提交/回滚全局事务5. 异步删除undo_log5. 根据undo_log生成反向SQL回滚alt[提交成功][回滚]TM(应用)TC(Seata Server)RM(数据库)

2. 关键机制

  • SQL 解析:拦截业务 SQL,生成前后镜像(before image / after image)。
  • 全局锁:避免其他事务修改正在处理的数据(如 SELECT FOR UPDATE)。
  • undo_log 表:存储回滚日志,与业务数据在同一个本地事务中提交。

undo_log 表示例

CREATE TABLE undo_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    xid VARCHAR(100) NOT NULL COMMENT '全局事务ID',
    branch_id BIGINT NOT NULL COMMENT '分支事务ID',
    rollback_info LONGBLOB NOT NULL COMMENT '回滚日志',
    log_status INT NOT NULL COMMENT '状态',
    log_created DATETIME NOT NULL,
    log_modified DATETIME NOT NULL
);

四、TCC 模式实现要点

1. 接口定义

// 库存服务 TCC 接口
public interface InventoryService {
    @TwoPhaseBusinessAction(name = "freeze", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean freeze(@BusinessActionContextParameter("productId") String productId, 
                   @BusinessActionContextParameter("count") int count);
​
    boolean confirm(BusinessActionContext context);
    boolean cancel(BusinessActionContext context);
}

2. 异常处理

  • 空回滚:Cancel 时检查 Try 是否执行,未执行则记录日志。
  • 悬挂:Try 前检查 Cancel 是否已执行,避免无效预留。
  • 幂等性:通过事务ID(XID)确保接口多次调用结果一致。

五、Saga 模式实现示例

1. 状态机配置(JSON)

{
  "name": "orderSaga",
  "steps": [
    {
      "name": "createOrder",
      "service": "orderService",
      "compensate": "cancelOrder"
    },
    {
      "name": "deductInventory",
      "service": "inventoryService",
      "compensate": "restoreInventory"
    }
  ]
}

2. 补偿逻辑

public class OrderService {
    public void cancelOrder(String orderId) {
        // 幂等性检查
        if (orderDao.isCancelled(orderId)) return;
        // 取消订单并恢复库存
        orderDao.updateStatus(orderId, "CANCELLED");
        inventoryService.restore(orderId);
    }
}

六、Seata 部署与配置

1. TC Server 部署

  • 下载地址Seata GitHub Release

  • 配置存储模式

    • file:单机模式(默认)。
    • db:高可用模式,需配置数据库(MySQL)。
    • redis:集群模式。

db 模式配置(registry.conf)

registry {
  type = "nacos"
  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    cluster = "default"
  }
}
​
config {
  type = "nacos"
  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    group = "SEATA_GROUP"
  }
}

2. 客户端配置(application.yml)

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
  config:
    type: nacos
    nacos:
      server-addr: localhost:8848

七、最佳实践与常见问题

1. 性能优化

  • AT 模式

    • 避免大事务,减少全局锁持有时间。
    • 关闭不必要的 SQL 解析(如只读查询)。
  • TCC 模式

    • 异步执行 Confirm/Cancel 操作。
    • 使用 Redis 缓存事务状态,减少数据库压力。

2. 高可用部署

  • TC 集群:通过 Nacos/Eureka 注册中心实现多节点部署。
  • 数据库 HA:配置 MySQL 主从复制或集群。

3. 常见问题

  • 全局锁冲突:优化业务逻辑,减少竞争;或切换至 TCC 模式。
  • undo_log 堆积:定时清理已提交的事务日志。
  • 网络分区:结合熔断机制(如 Sentinel),超时后触发本地事务回滚。

八、总结

Seata 的核心价值在于提供了一套灵活、多模式的分布式事务解决方案:

  • 简单场景:AT 模式无侵入,快速接入。
  • 高性能需求:TCC 模式避免锁竞争,适合高并发。
  • 长流程业务:Saga 模式通过补偿链实现最终一致。
  • 强一致性要求:XA 模式兼容传统数据库。

部署公式

Seata = TC(协调中心) + TM/RM(客户端) + 事务模式(AT/TCC/Saga/XA) → 分布式事务管理