⚙️ 一、AT 模式的核心机制
1. 两阶段提交优化
-
一阶段(业务执行):
-
解析业务 SQL,生成前镜像 (before image)和后镜像(after image)。
-
执行业务 SQL 并提交本地事务,释放本地锁。
-
插入回滚日志(
undo_log
表)并向 TC(事务协调者)注册分支事务,申请全局锁135。
-
-
二阶段(异步提交/补偿回滚):
-
提交 :异步删除
undo_log
记录,释放全局锁。 -
回滚 :根据
undo_log
中的前镜像生成反向 SQL 回滚数据,校验数据一致性(防止脏写)348。
-
2. 全局锁解决脏写问题
-
一阶段提交前,RM(资源管理器)需获取目标数据的全局锁。
-
若其他事务尝试修改同一数据,需等待全局锁释放(超时则回滚本地事务),避免脏写14。
📊 二、AT 模式 vs. XA 模式
特性 | AT 模式 | XA 模式 |
---|---|---|
锁占用时间 | 一阶段提交后释放本地锁 | 整个事务过程持有锁 |
性能 | 高(二阶段异步提交) | 低(同步阻塞) |
数据一致性 | 默认读未提交(通过 SELECT FOR UPDATE 支持读已提交) |
强一致性 |
侵入性 | 无侵入(代理数据源) | 需数据库支持 XA 协议 |
🔧 三、AT 模式的实现步骤
1. 环境准备
-
数据库 :创建
undo_log
表(必需的回滚日志存储)4:sql
复制
下载
CREATE TABLE undo_log ( id BIGINT AUTO_INCREMENT PRIMARY KEY, branch_id BIGINT NOT NULL, xid VARCHAR(100) NOT NULL, rollback_info LONGBLOB NOT NULL, log_status INT NOT NULL, log_created DATETIME NOT NULL, log_modified DATETIME NOT NULL, INDEX idx_xid (xid) );
2. Seata 服务端(TC)配置
-
启动命令:
sh seata-server.sh -p 8091 -h 0.0.0.0
-
存储模式建议使用
db
(高可用),配置 MySQL 存储全局事务信息6。
3. 客户端集成(Spring Cloud)
-
依赖:
xml
复制
下载
运行
<dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.6.1</version> </dependency>
-
数据源代理:
java
复制
下载
@Bean public DataSource dataSource(DruidDataSource druidDataSource) { return new DataSourceProxy(druidDataSource); // 关键:代理原生数据源 }
-
全局事务注解:
java
复制
下载
@GlobalTransactional public void createOrder() { orderService.insert(); // 本地事务 storageFeignClient.deduct(); // 远程调用(RM 自动注册分支事务) }
⚠️ 四、注意事项与最佳实践
-
SQL 规范:
-
操作必须包含主键(用于生成前后镜像)。
-
不支持无条件的
UPDATE/DELETE
语句(避免全表更新)38。
-
-
隔离性保障:
- 默认全局读未提交,需读已提交时使用
SELECT FOR UPDATE
(自动申请全局锁)4。
- 默认全局读未提交,需读已提交时使用
-
性能优化:
-
异步删除
undo_log
:配置client.undo.logDeletePeriod=86400000
(每日清理)。 -
索引优化:为
undo_log
表的xid
和status
字段添加索引6。
-
-
高可用部署:
-
TC 集群:通过注册中心(如 Nacos)实现多节点部署。
-
数据库存储:使用 MySQL/Oracle 替代
file
模式6。
-
💎 总结
Seata AT 模式以 无侵入性 和 高性能异步提交 为核心优势,适用于大多数微服务场景。通过全局锁和回滚日志机制,在保证数据一致性的同时避免了传统 XA 协议的资源阻塞问题。对于新项目,AT 模式是快速落地分布式事务的首选方案;复杂场景可结合 TCC 或 Saga 模式补充64。
示例代码及 TC 配置详见 Seata 官方文档。