Seata架构设计解析:TC核心算法与AT模式实现
Seata架构设计与实现原理深度解析
一、事务协调器(TC)核心算法
1. 全局事务生命周期管理
TC作为分布式事务的"大脑",其核心算法体现在全局事务的完整生命周期控制:
// 伪代码展示TC核心处理流程
public class TransactionCoordinator {
// 全局事务开始
public String begin(String applicationId, String transactionGroup, int timeout) {
String xid = generateXID(); // 生成全局唯一事务ID
GlobalTransaction tx = new GlobalTransaction(xid, timeout);
tx.setStatus(Begin);
transactionRepository.store(tx); // 持久化事务日志
return xid;
}
// 全局提交(两阶段提交第一阶段)
public void commit(String xid) {
GlobalTransaction tx = transactionRepository.find(xid);
for (BranchTransaction branch : tx.getBranches()) {
sendPhase1CommitToRM(branch); // 向所有RM发送准备请求
}
tx.setStatus(Committing);
}
// 全局提交(两阶段提交第二阶段)
public void doGlobalCommit(String xid) {
// 确认所有分支事务都准备成功后执行提交
tx.setStatus(Committed);
}
}
实践建议:
- 事务超时时间应根据业务场景合理设置(默认60秒)
- 全局事务ID(XID)会通过线程上下文传递,避免业务代码中手动传递
2. 两阶段提交优化实现
Seata对传统2PC做了以下关键优化:
优化点 | 传统2PC | Seata 2PC |
---|---|---|
阻塞时间 | 两阶段都同步等待 | 第一阶段异步化 |
锁持有时间 | 整个事务期间 | 仅第二阶段短暂持有 |
故障恢复 | 依赖数据库日志 | 独立事务日志存储 |
实践建议:
- 生产环境建议开启TC集群部署,避免单点故障
- 对于高频短事务可适当调小
client.rm.report.retry.count
减少重试开销
二、分布式事务模型实现原理
1. AT模式undo_log设计
AT模式的核心在于通过解析SQL生成反向补偿日志:
-- undo_log表示例结构
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
);
undo_log记录示例:
{
"beforeImage": {
"rows": [{
"fields": [{
"name": "amount",
"type": "DECIMAL",
"value": "100.00"
}]
}]
},
"afterImage": {
"rows": [{
"fields": [{
"name": "amount",
"type": "DECIMAL",
"value": "80.00"
}]
}]
}
}
实践建议:
- undo_log表应与业务表在同一数据库实例
- 定期清理已完成的undo日志(默认保存7天)
2. TCC模式接口契约
TCC模式要求业务必须实现三个接口:
// 账户服务TCC接口示例
@LocalTCC
public interface AccountTccService {
@TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")
boolean deduct(@BusinessActionContextParameter(paramName = "userId") String userId,
@BusinessActionContextParameter(paramName = "money") BigDecimal money);
boolean confirm(BusinessActionContext context);
boolean cancel(BusinessActionContext context);
}
TCC实现要点:
- Try阶段:预留资源(如冻结金额)
- Confirm阶段:确认使用预留资源(如扣除冻结金额)
- Cancel阶段:释放预留资源(如解冻金额)
实践建议:
- 所有TCC接口必须实现幂等性
- 建议使用
@BusinessActionContextParameter
传递上下文参数
3. Saga状态机设计
Saga模式通过状态机管理长事务流程:
// 订单创建Saga示例
{
"name": "createOrderSaga",
"steps": [
{
"name": "createOrder",
"service": "orderService",
"compensate": "cancelOrder"
},
{
"name": "reserveInventory",
"service": "inventoryService",
"compensate": "releaseInventory"
}
]
}
补偿机制特点:
- 正向服务与补偿服务必须配对出现
- 补偿服务按反向顺序执行
- 支持异步补偿和手动触发补偿
三、高可用架构设计
1. TC Server集群部署
RAFT选举关键参数:
# store.mode=raft时生效
server.raft.server-addr=192.168.1.1:7091
server.raft.group=seata_group
server.raft.snapshot-interval=3600
2. 事务日志存储方案对比
存储类型 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
文件存储 | 部署简单,性能好 | 可靠性较低 | 开发测试环境 |
数据库存储 | 数据可靠,支持查询 | 性能开销较大 | 生产环境 |
Redis存储 | 高性能,低延迟 | 持久化依赖配置 | 高频短事务场景 |
实践建议:
- 生产环境推荐使用数据库存储(MySQL集群)
- 文件存储模式下应配置共享存储(如NFS)
3. 故障转移策略
Seata与注册中心协同实现故障转移:
- TC节点定时发送心跳到注册中心
- 客户端缓存TC节点列表并实现负载均衡
- 当节点不可达时自动切换到健康节点
关键配置:
# Nacos注册中心配置示例
registry.type=nacos
registry.nacos.application=seata-server
registry.nacos.server-addr=127.0.0.1:8848
总结与最佳实践
模式选型建议:
- 简单业务:优先使用AT模式
- 需要强隔离性:选择TCC模式
- 长流程业务:采用Saga模式
性能调优方向:
- 减少全局锁竞争(细化业务锁粒度)
- 合理设置事务超时时间
- 根据业务特点选择适当的存储模式
高可用保障:
- TC集群至少部署3节点
- 生产环境使用数据库存储事务日志
- 实现多机房容灾部署
通过深入理解Seata的架构设计原理,可以更合理地应用于实际业务场景,在保证数据一致性的同时获得最佳性能表现。
评论已关闭