Seata采用三层架构设计,各组件协同工作:
TC (Transaction Coordinator)
全局事务大脑,负责事务生命周期管理
核心功能:
全局事务的发起与终止
分支事务的注册与状态管理
全局锁的分配与释放
部署方式:独立服务,支持集群部署
TM (Transaction Manager)
事务发起方,定义事务边界
关键行为:
通过@GlobalTransactional
注解声明全局事务
决定全局事务的提交或回滚
与TC保持心跳检测
RM (Resource Manager)
资源管理者,处理分支事务
核心职责:
向TC注册分支事务
报告分支事务状态
执行TC的提交/回滚指令
管理本地资源(如数据库连接)
Seata通过XID(全局事务ID)实现跨服务调用的事务上下文传播:
XID生成:TM发起全局事务时,TC生成唯一XID
上下文注入:
java
复制
下载
// Feign拦截器示例 public class SeataFeignInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { String xid = RootContext.getXID(); if (StringUtils.isNotBlank(xid)) { template.header(RootContext.KEY_XID, xid); } } }
跨服务传递:通过HTTP Header/RPC上下文传递XID
分支关联:RM通过XID将分支事务与全局事务关联
阶段一:业务执行
SQL解析:使用Druid解析SQL,提取表、条件等信息
前镜像生成:
SELECT * FROM product WHERE id = 1 FOR UPDATE
业务SQL执行:
UPDATE product SET stock = stock - 1 WHERE id = 1
后镜像生成:
SELECT * FROM product WHERE id = 1
undo_log记录:
{ "branchId": 641253, "xid": "192.168.1.1:8091:641253", "rollbackInfo": { "beforeImage": { "rows": [{"id":1,"stock":10}] }, "afterImage": { "rows": [{"id":1,"stock":9}] } } }
阶段二:全局提交
TC异步通知各RM删除undo_log
释放全局锁
阶段二:全局回滚
校验脏写:比较当前数据与afterImage
生成补偿SQL:
UPDATE product SET stock = 10 WHERE id = 1
提交补偿事务
删除undo_log
全局锁设计
存储结构:global_table
表存储锁记录
获取流程:
检查是否存在冲突锁
插入锁记录(行锁)
设置锁超时(默认60s)
undo_log优化
压缩存储:对大字段进行压缩
异步清理:后台线程定期清理已提交的事务日志
分表设计:按xid哈希分表存储
账户服务TCC接口:
public interface AccountTccService { @TwoPhaseBusinessAction(name = "freezeAmount", commitMethod = "confirm", rollbackMethod = "cancel") boolean freeze(@BusinessActionContextParameter(paramName = "userId") Long userId, @BusinessActionContextParameter(paramName = "amount") BigDecimal amount); boolean confirm(BusinessActionContext context); boolean cancel(BusinessActionContext context); }
Try阶段实现:
@Override public boolean freeze(Long userId, BigDecimal amount) { // 检查账户状态 Account account = accountDao.selectById(userId); if (account.getStatus() != AccountStatus.ACTIVE) { throw new IllegalStateException("账户非活跃状态"); } // 检查余额是否充足 if (account.getAvailable().compareTo(amount) < 0) { throw new IllegalArgumentException("余额不足"); } // 冻结金额 accountDao.freezeAmount(userId, amount); // 记录冻结流水 FreezeRecord record = new FreezeRecord(); record.setXid(RootContext.getXID()); record.setUserId(userId); record.setAmount(amount); freezeRecordDao.insert(record); return true; }
Cancel阶段异常处理:
@Override public boolean cancel(BusinessActionContext context) { // 处理空回滚 if (!freezeRecordDao.exists(context.getXid())) { log.warn("收到未执行try的空回滚,xid={}", context.getXid()); return true; } // 幂等控制 if (freezeRecordDao.isCanceled(context.getXid())) { return true; } // 执行解冻 Long userId = context.getActionContext("userId"); BigDecimal amount = context.getActionContext("amount"); try { accountDao.unfreezeAmount(userId, amount); freezeRecordDao.markCanceled(context.getXid()); } catch (Exception e) { // 重试机制 throw new SeataTccException("解冻失败,需要重试", e); } return true; }
服务设计原则:
预留资源要充足
Confirm必须幂等
Cancel需要处理空回滚
事务日志设计:
CREATE TABLE tcc_action_record ( id BIGINT PRIMARY KEY, xid VARCHAR(128) NOT NULL, action_name VARCHAR(64) NOT NULL, status TINYINT NOT NULL, -- 1:TRY,2:CONFIRM,3:CANCEL args_json TEXT, create_time DATETIME, update_time DATETIME, UNIQUE KEY uk_xid_action (xid, action_name) );
超时处理机制:
设置合理的事务超时时间
实现定时任务扫描悬挂事务
提供人工干预接口
订单流程状态机:
StateMachineBuilderbuilder = StateMachineBuilderFactory.create(); builder.externalTransition() .from(OrderState.INIT) .to(OrderState.PAYING) .on(OrderEvent.PAY) .when(checkCondition()) .perform(doAction()); builder.externalTransition() .from(OrderState.PAYING) .to(OrderState.PAID) .on(OrderEvent.PAY_SUCCESS) .when(checkCondition()) .perform(doAction()); builder.externalTransition() .from(OrderState.PAYING) .to(OrderState.FAILED) .on(OrderEvent.PAY_FAILED) .when(checkCondition()) .perform(compensationAction());
并行补偿策略:
public class ParallelCompensationStrategy implements CompensationStrategy { @Override public void compensate(Listtransactions) { transactions.parallelStream().forEach(tx -> { try { tx.compensate(); } catch (Exception e) { log.error("补偿执行失败", e); // 记录失败,后续重试 compensationFailureRecorder.record(tx); } }); } }
顺序补偿策略:
public class SequentialCompensationStrategy implements CompensationStrategy { @Override public void compensate(Listtransactions) { for (Transaction tx : transactions) { int retry = 0; while (retry < MAX_RETRY) { try { tx.compensate(); break; } catch (Exception e) { retry++; if (retry == MAX_RETRY) { throw new CompensationException("补偿最终失败"); } sleep(1000 * retry); } } } } }
数据源代理配置:
@Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DruidDataSource druidDataSource() { return new DruidDataSource(); } @Primary @Bean public DataSource dataSource(DruidDataSource druidDataSource) { return new DataSourceProxyXA(druidDataSource); } }
XA事务日志表:
CREATE TABLE xa_log ( xid VARCHAR(128) NOT NULL, branch_id VARCHAR(128) NOT NULL, status TINYINT NOT NULL, gmt_create DATETIME NOT NULL, gmt_modified DATETIME NOT NULL, PRIMARY KEY (xid, branch_id) );
连接池优化:
spring: datasource: druid: initial-size: 5 max-active: 20 min-idle: 5 max-wait: 60000 validation-query: SELECT 1 test-while-idle: true test-on-borrow: false
批量操作优化:
@GlobalTransactional public void batchImport(Listproducts) { jdbcTemplate.batchUpdate( "INSERT INTO product(name,price) VALUES(?,?)", products, 100, // 批处理大小 (ps, product) -> { ps.setString(1, product.getName()); ps.setBigDecimal(2, product.getPrice()); }); }
订单创建流程:
@GlobalTransactional public void createOrder(OrderDTO orderDTO) { // AT模式操作:订单记录创建 orderMapper.insert(orderDTO); // TCC模式调用:库存扣减 inventoryTccService.reduceStock( orderDTO.getProductId(), orderDTO.getQuantity()); // AT模式操作:日志记录 orderLogService.recordCreateLog(orderDTO); }
跨境支付流程:
@SagaStart public void crossBorderPayment(PaymentRequest request) { // TCC模式:冻结本地账户资金 accountTccService.freeze( request.getUserId(), request.getAmount()); // 调用外汇服务(AT模式) exchangeService.convert( request.getFromCurrency(), request.getToCurrency(), request.getAmount()); // 调用境外支付(SAGA模式) foreignPaymentService.pay( request.getToAccount(), request.getConvertedAmount()); }
server端配置:
properties
# 事务日志存储模式(推荐DB) store.mode=db # 全局事务超时时间(毫秒) server.max.commit.retry.timeout=60000 server.max.rollback.retry.timeout=60000 # 全局锁竞争检测间隔 server.lock.retry.internal=10 server.lock.retry.times=30
client端配置:
properties
# RM报告重试次数 client.rm.report.retry.count=5 # 全局锁获取超时时间 client.lock.retry.timeout=30000 # 异步提交缓冲队列大小 client.async.commit.buffer.limit=10000
Prometheus监控指标:
metrics: enabled: true registry-type: compact exporter-list: prometheus exporter-prometheus-port: 9898
关键监控指标:
全局事务成功率
各模式事务平均耗时
全局锁竞争次数
二阶段提交/回滚延迟
资源占用情况
全局锁冲突:
优化方案:
减小事务粒度
添加重试机制
@Retryable(maxAttempts=3, backoff=@Backoff(delay=100)) public void doBusiness() { // 业务逻辑 }
应急方案:
临时提高锁超时时间
人工干预解除锁
事务悬挂:
预防措施:
完善空回滚处理
添加事务状态校验
检测方案:
SELECT * FROM undo_log WHERE gmt_create < DATE_SUB(NOW(), INTERVAL 1 HOUR) AND status = 'PREPARED';
TC集群故障处理:
快速恢复方案:
备用TC集群切换
事务日志恢复
业务降级方案:
本地事务保障核心流程
消息队列补偿最终一致性
云原生支持:
容器化部署优化
Service Mesh集成
K8s Operator开发
多语言生态:
Go语言实现
Python客户端支持
Node.js适配
新特性规划:
分布式事务链追踪
智能模式推荐
自动熔断降级