Seata AT模式详解:无侵入的高性能分布式事务
·
Seata AT模式详解:无侵入的高性能分布式事务 🚀
|
🌺The Begin🌺点点关注,收藏不迷路🌺
|
引言:从XA到AT的进化
XA模式虽然保证了强一致,但最大的痛点是资源锁定周期过长——从第一阶段开始锁定,直到第二阶段结束才释放,严重影响并发性能。
AT模式同样采用两阶段提交,但巧妙解决了这个问题:第一阶段就提交本地事务释放锁,通过undo-log保证可回滚。
一、AT模式核心思想 🎯
1.1 关键创新
AT模式同样是分阶段提交的事务模型,不过却弥补了XA模型中资源锁定周期过长的缺陷。
| 对比项 | XA模式 | AT模式 |
|---|---|---|
| 一阶段 | 执行SQL,不提交,锁定资源 | 执行SQL,立即提交,释放资源 |
| 资源锁定 | 整个事务期间 | 仅业务执行期间 |
| 回滚依据 | 数据库undo日志 | 自定义undo-log表 |
| 性能 | 低 | 高 |
1.2 核心原理
AT模式通过**记录数据快照(undo-log)**来实现回滚能力,而不是依赖数据库锁:
-- AT模式的核心: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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二、完整业务示例:账户余额更新 💰
2.1 初始数据
假设有一个数据库表,记录用户余额:
| id | money |
|---|---|
| 1 | 100 |
其中一个分支业务要执行的SQL为:
UPDATE account SET money = money - 10 WHERE id = 1;
2.2 一阶段执行流程
一阶段详细步骤:
- TM发起并注册全局事务到TC
- TM调用分支事务
- 分支事务准备执行业务SQL
- RM拦截业务SQL,根据where条件查询原始数据,形成快照(前镜像)
前镜像:{"id": 1, "money": 100} - RM执行业务SQL,提交本地事务,释放数据库锁
执行后:money = 90 - RM记录后镜像并报告状态
后镜像:{"id": 1, "money": 90}
2.3 二阶段执行流程
场景1:全局提交(所有分支成功)
public class CommitPhase {
// 二阶段提交时RM的工作
public void commit() {
// 只需要删除undo-log即可
undoLogDao.deleteByXidAndBranchId(xid, branchId);
// 业务数据已经提交,无需额外操作
}
}
场景2:全局回滚(有分支失败)
public class RollbackPhase {
// 二阶段回滚时RM的工作
public void rollback() {
// 1. 读取快照数据
UndoLog log = undoLogDao.findByXidAndBranchId(xid, branchId);
// 2. 解析前镜像
// 前镜像:{"id": 1, "money": 100}
TableRecords beforeImage = log.getBeforeImage();
// 3. 根据前镜像生成回滚SQL
String rollbackSql = buildRollbackSql(beforeImage);
// 例如:UPDATE account SET money = 100 WHERE id = 1
// 4. 执行回滚
jdbcTemplate.execute(rollbackSql);
// 5. 删除已使用的undo-log
undoLogDao.delete(log);
// 此时数据库再次恢复为100
}
}
三、AT模式完整时序图 🔄
四、AT模式的核心优势 🌟
4.1 资源锁定时间对比
| 阶段 | XA模式 | AT模式 |
|---|---|---|
| 业务执行期间 | 锁定资源 | 锁定资源 |
| 等待二阶段期间 | 仍锁定资源 | 资源已释放 |
| 总锁定时间 | 长 | 短(仅业务执行期) |
4.2 性能对比
public class PerformanceComparison {
// XA模式:锁等待
// 事务1: UPDATE account SET money=90 WHERE id=1 (锁定中)
// 事务2: UPDATE account SET money=80 WHERE id=1 (必须等待事务1结束)
// AT模式:无锁等待
// 事务1: UPDATE account SET money=90 WHERE id=1 (立即提交,释放锁)
// 事务2: UPDATE account SET money=80 WHERE id=1 (无需等待,直接执行)
// 如果事务1需要回滚,事务2可能已执行,需要全局回滚
}
五、XA vs AT 模式对比 📊
| 对比维度 | XA模式 | AT模式 |
|---|---|---|
| 资源锁定 | 整个事务期间 | 仅业务执行期间 |
| 一阶段 | 执行不提交,锁定资源 | 执行并提交,释放资源 |
| 二阶段提交 | 提交事务 | 删除undo-log |
| 二阶段回滚 | 数据库回滚 | 根据undo-log恢复 |
| 性能 | 低 | 高 |
| 一致性 | 强一致 | 最终一致 |
| 代码侵入 | 无 | 无 |
六、总结 🎯
6.1 一句话总结
AT模式通过"业务SQL立即提交释放锁 + undo-log保证可回滚"的创新设计,在保证最终一致性的前提下,大幅提升了分布式事务的性能,是Seata最核心、最常用的模式。
6.2 核心价值
| 价值 | 说明 |
|---|---|
| 高性能 | 资源锁定时间短,并发高 |
| 无侵入 | 只需一个@GlobalTransactional注解 |
| 可靠 | undo-log保证可回滚 |
| 通用 | 适用于大多数业务场景 |
6.3 选型建议
public class Advice {
public String chooseMode() {
return "1. 通用业务、高并发场景 → AT模式(首选)\n"
+ "2. 强一致、低并发场景 → XA模式\n"
+ "3. 资源预留、极致性能 → TCC模式";
}
}
(本文为分布式系统事务系列文章,欢迎关注更多架构深度内容)

|
🌺The End🌺点点关注,收藏不迷路🌺
|
更多推荐





所有评论(0)