Seata:分布式事务解决方案
一、核心功能
-
事务模式支持
- AT模式(自动事务):
通过代理数据源自动生成回滚日志,实现零代码入侵。适用于大多数业务场景,但对数据持有全局锁(引用[4])。
示例:@GlobalTransactional注解开启分布式事务 - TCC模式(手动事务):
需实现Try/Confirm/Cancel三阶段接口,性能更高但需手动编码。Confirm操作必须保证幂等性(引用[5])。
配置示例(引用[3]):<bean class="io.seata.spring.annotation.GlobalTransactionScanner"> <constructor-arg value="tcc-sample"/> <constructor-arg value="my_test_tx_group"/> </bean>
- AT模式(自动事务):
-
服务治理集成
支持Nacos、Zookeeper、Eureka、Consul等注册中心,实现服务发现与负载均衡(引用[2])。 -
高可用架构
- 事务协调器(TC):核心组件,负责全局事务的提交/回滚(引用[1])。
- 支持集群部署,通过注册中心实现节点动态管理。
二、使用指南
-
快速接入步骤
graph LR A[引入依赖] --> B[配置注册中心] B --> C[添加数据源代理] C --> D[使用@GlobalTransactional]- 依赖配置:Java项目添加
seata-spring-boot-starter - 关键配置项:
seata.tx-service-group=my_tx_group seata.registry.type=nacos
- 依赖配置:Java项目添加
-
多语言支持
- Go语言:通过
seata-golang实现分布式事务(引用[4])。 - 跨语言方案:基于HTTP API或gRPC协议集成。
- Go语言:通过
三、最新动态(2023-2024)
-
云原生适配
- 支持Kubernetes Operator实现自动化部署
- 集成Service Mesh(如Istio)
-
性能优化
- AT模式全局锁优化(减少锁持有时间)
- 支持Redis作为事务日志存储
-
生态扩展
- 新增对Sofa注册中心的官方支持(引用[2])
- 增强与Apache Dubbo 3.x的兼容性
思维导图

Seata 技术原理详解
一、核心架构与组件
-
核心组件功能:
- TC (Transaction Coordinator):
全局事务协调器,维护全局事务状态(GlobalSession)和分支事务状态(BranchSession)。
数据结构:class GlobalSession { String xid; // 全局事务ID int status; // 状态:Begin, Committing, Rollbacking List<BranchSession> branches; // 分支事务集合 } - TM (Transaction Manager):
定义事务边界,通过@GlobalTransactional发起全局事务,生成全局唯一XID。 - RM (Resource Manager):
管理分支事务,拦截SQL生成回滚日志(AT模式),实现本地资源与TC的通信。
- TC (Transaction Coordinator):
-
数据流转:
[TM] -- 开启事务 --> [TC] [RM] -- 注册分支事务 --> [TC] [TC] -- 提交/回滚指令 --> [RM]
二、关键技术原理
-
AT模式(Auto Transaction):
- 两阶段提交算法:
- 全局锁机制:
通过TC维护branch_table(分支事务表)和lock_table(全局锁表),防止脏写。
伪代码:// 检查全局锁 boolean lock = checkLock(branchSession); if (!lock) throw new LockConflictException();
- 两阶段提交算法:
-
TCC模式(Try-Confirm-Cancel):
- 三阶段算法:
Try → { Confirm if ∑ Try = success Cancel otherwise \text{Try} \rightarrow \begin{cases} \text{Confirm} & \text{if } \sum\text{Try} = \text{success} \\ \text{Cancel} & \text{otherwise} \end{cases} Try→{ConfirmCancelif ∑Try=successotherwise - 幂等性设计:
通过tcc_fence_log表记录状态,确保Confirm/Cancel只执行一次。
- 三阶段算法:
-
关键数据结构:
- undo_log表(AT模式核心):
字段 说明 branch_id 分支事务ID xid 全局事务ID rollback_info 回滚SQL的JSON数据 log_status 状态(0-正常,1-已回滚)
- undo_log表(AT模式核心):
三、优缺点分析
| 优点 | 挑战 |
|---|---|
| 1. AT模式零代码入侵 | 1. AT模式全局锁可能成性能瓶颈 |
| 2. 支持多语言(Java/Go等) | 2. TCC模式需业务改造 |
| 3. 高可用架构(TC集群部署) | 3. 跨网络调用增加延迟 |
| 4. 兼容主流注册中心(Nacos等) | 4. 热点数据并发冲突需特殊处理 |
四、Java代码示例(AT模式)
// 订单服务
@GlobalTransactional(name = "createOrder", timeoutMills = 60000)
public void createOrder(Order order) {
// 1. 本地事务:创建订单
orderMapper.insert(order); // RM自动生成undo_log
// 2. 远程调用:扣减库存
storageFeignService.deduct(order.getProductId(), order.getCount());
// 若此处抛出异常,Seata自动触发全局回滚
}
// 库存服务
@Transactional
public void deduct(String productId, int count) {
// 本地事务:扣减库存
storageMapper.updateStock(productId, count);
// RM拦截SQL生成回滚SQL:UPDATE stock SET count=count+? WHERE id=?
}
五、最佳实践
-
AT模式适用场景:
- 标准CRUD操作
- 低并发热点数据
- 需要快速接入的项目
-
性能优化建议:
# 减小锁等待时间 seata.client.lock.retryInterval=10ms seata.client.lock.retryTimes=3 # 使用Redis存储事务日志 seata.server.session.storeMode=redis
关键技术点总结:
- AT模式通过SQL解析+undo_log实现自动回滚
- 全局事务ID(XID)贯穿整个调用链
- TC通过两阶段提交+全局锁保证强一致性
- 回滚机制依赖前置镜像(before image)和后置镜像(after image)
思维导图

Seata分布式事务机制深度解析
一、AT模式脏读问题解决方案
核心原理:全局锁机制 + 读隔离级别
-
全局锁实现:
- 更新数据前,RM向TC申请全局锁
- 未获锁的事务会被阻塞或失败(默认等待重试)
- 关键数据结构:
class LockTable { Map<String, LockOwner> locks; // key: 行主键 } class LockOwner { String xid; // 全局事务ID Long branchId; // 分支事务ID }
-
读隔离级别:
- 默认Read Committed:读取最新已提交数据
- 升级Read Uncommitted:配置
@GlobalTransactional(readOnly = true) - 快照读实现:
// 数据源代理拦截查询 public class SelectExecutor { public Object execute() { if (hasGlobalLock()) { // 检查全局锁 return queryCurrentData(); // 读最新数据 } else { return queryUndoLog(); // 读undo_log前镜像 } } } - 通过
undo_log表的前镜像(before image)提供一致性视图
二、TCC模式幂等性设计
核心方案:防悬挂控制表 + 状态机
-
幂等性保障:
- 创建
tcc_fence_log表记录事务状态:字段 类型 说明 xid VARCHAR(128) 全局事务ID branch_id BIGINT 分支事务ID status TINYINT 状态(1-Try,2-Confirm,3-Cancel) gmt_create DATETIME 创建时间
- 创建
-
代码实现:
@Service public class InventoryTccServiceImpl { // TCC防悬挂检查 @Transactional public boolean deduct(String xid, Long branchId, int count) { // 检查防悬挂记录 if (tccFenceDao.isExist(xid, branchId)) { return true; // 幂等返回 } // 执行业务Try逻辑 int affected = inventoryDao.freezeStock(itemId, count); if (affected == 0) { throw new RuntimeException("库存不足"); } // 插入防悬挂记录 tccFenceDao.insert(xid, branchId, TccStatus.TRY); } // Confirm幂等实现 @Transactional public boolean confirm(String xid, Long branchId) { if (tccFenceDao.getStatus(xid, branchId) != TccStatus.TRY) { return true; // 已处理过 } // 执行业务逻辑 inventoryDao.reduceFrozenStock(itemId, count); // 更新状态 tccFenceDao.updateStatus(xid, branchId, TccStatus.CONFIRM); } // Cancel幂等实现(类似Confirm) @Transactional public boolean cancel(String xid, Long branchId) { // 状态检查... inventoryDao.releaseFrozenStock(itemId, count); tccFenceDao.updateStatus(xid, branchId, TccStatus.CANCEL); } }
三、RocketMQ事务消息整合
实现原理:二阶段提交 + 消息状态回查
关键集成点:
- 事务监听器:
public class OrderTransactionListener implements TransactionListener { @Override public LocalTransactionState execute(Message msg, Object arg) { // 开启Seata事务 GlobalTransaction tx = GlobalTransactionContext.begin(); try { // 执行业务操作 orderService.createOrder(parseOrder(msg)); return LocalTransactionState.COMMIT_MESSAGE; } catch (Exception e) { tx.rollback(); return LocalTransactionState.ROLLBACK_MESSAGE; } } // 回查机制(Seata TC提供状态查询API) public LocalTransactionState check(MessageExt msg) { String xid = msg.getUserProperty("SEATA_XID"); GlobalStatus status = DefaultTransactionManager.get(xid); return status == GlobalStatus.Committed ? LocalTransactionState.COMMIT_MESSAGE : LocalTransactionState.ROLLBACK_MESSAGE; } }
四、Metrics监控实现
监控体系:
-
关键指标:
- 事务成功率:
seata.transaction.success.rate - TPS:
seata.transaction.count - 平均耗时:
seata.transaction.avg.time
- 事务成功率:
-
配置步骤:
# file.conf metrics { enabled = true registryType = "compact" exporterList = "prometheus" exporterPrometheusPort = 9898 }Prometheus抓取配置:
scrape_configs: - job_name: 'seata' static_configs: - targets: ['seata-tc:9898'] -
Grafana看板:
- 官方提供标准仪表盘模板
- 核心面板:
- 全局事务成功率
- 分支事务TP99耗时
- 全局锁竞争次数
五、Kubernetes高可用方案
架构实现:
-
核心配置:
# StatefulSet配置 kind: StatefulSet spec: serviceName: "seata-tc" replicas: 3 template: spec: containers: - name: seata-server env: - name: SEATA_IP valueFrom: {fieldRef: {fieldPath: status.podIP}} args: ["-h", "$(SEATA_IP)"] -
高可用要点:
- 存储层:使用云原生数据库(如TiDB)或MySQL集群
- 服务发现:集成Nacos集群
- 配置中心:Nacos Config统一管理配置
- 负载均衡:K8s Service实现负载均衡
六、AT模式与TCC模式对比
| 维度 | AT模式 | TCC模式 |
|---|---|---|
| 实现原理 | 基于SQL解析+undo_log回滚 | 业务补偿+三阶段提交 |
| 侵入性 | 低(数据源代理) | 高(需实现Try/Confirm/Cancel) |
| 性能 | 中(两阶段提交) | 高(无全局锁) |
| 一致性 | 强一致性 | 最终一致性 |
| 适用场景 | 标准CRUD操作 | 高并发、复杂业务逻辑 |
| 锁机制 | 全局锁(可能死锁) | 无锁 |
| 回滚能力 | 自动生成回滚SQL | 需手动实现回滚逻辑 |
七、Nacos集成配置
-
TC端配置(registry.conf):
registry { type = "nacos" nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" namespace = "public" cluster = "default" } } -
客户端配置(application.yml):
seata: registry: type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: public group: SEATA_GROUP config: type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: public group: SEATA_GROUP tx-service-group: my_tx_group
八、全局锁性能优化
-
优化策略:
-
具体措施:
- 调整锁超时参数:
# 客户端配置 client.lock.retryInterval=10 client.lock.retryTimes=3 - 使用Redis存储锁(需修改存储模式):
store.mode=redis - 热点数据并发控制:
@GlobalLock // 使用本地锁代替全局锁 public void updateHotspotData() { // 业务逻辑 }
- 调整锁超时参数:
九、数据源代理原理
实现机制:
public class DataSourceProxy extends AbstractDataSource {
private final DataSource targetDataSource;
// 创建代理连接
public Connection getConnection() throws SQLException {
return new ConnectionProxy(targetDataSource.getConnection());
}
// SQL拦截
private class ConnectionProxy {
public PreparedStatement prepareStatement(String sql) {
// SQL解析
SQLRecognizer recognizer = SQLVisitorFactory.get(sql);
// 生成前置镜像
if (recognizer.isUpdate()) {
TableRecords beforeImage = queryBeforeImage(recognizer);
}
// 执行原始SQL
PreparedStatement stmt = target.prepareStatement(sql);
// 生成后置镜像
if (recognizer.isUpdate()) {
TableRecords afterImage = queryAfterImage(recognizer);
// 生成undo_log
UndoLogManager.save(beforeImage, afterImage);
}
return stmt;
}
}
}
十、Spring Cloud Alibaba集成
关键配置:
spring:
cloud:
alibaba:
seata:
tx-service-group: my_seata_tx_group
enabled: true
enable-auto-data-source-proxy: true # 自动代理数据源
disable-global-transaction: false
注意事项:
- 版本兼容性:确保Spring Cloud Alibaba、Seata、Nacos版本匹配
- 数据源代理冲突:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class App { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return new DruidDataSource(); } // 手动创建代理 @Bean public DataSourceProxy dataSourceProxy(DataSource dataSource) { return new DataSourceProxy(dataSource); } } - Feign调用事务传播:
- 通过拦截器传递XID:
public class SeataFeignInterceptor implements RequestInterceptor { public void apply(RequestTemplate template) { String xid = RootContext.getXID(); template.header("TX_XID", xid); } }
- 通过拦截器传递XID:
十一、多语言支持
| 语言 | 支持情况 | 项目地址 |
|---|---|---|
| Java | 官方完整支持 | seata/seata |
| Go | 社区支持 | seata/seata-go |
| Python | 实验性支持 | opensearch-project/sql |
| C++ | 无官方支持 | - |
| 多语言接入 | HTTP API | 通过RESTful接口与TC交互 |
思维导图


343

被折叠的 条评论
为什么被折叠?



