面试记录 2026-09-23
题目:Seata 的 AT 模式的实现原理
难度:medium
评分:⭐⭐☆☆☆
我的回答
对于 seata 我了解不多,业务中使用分布式事务本身就比较少,尽可能的不去把事务做到不同的服务上。但是可能一些特殊场景会考虑到使用分布式事务,也会使用最终一致性的,很少。当前的业务,我接触的业务很少使用到强一致性的分布式事务。我印象中,AT 模式是强一致的事务,它是基于数据库的 undo log 去实现的,应该。它应该也是类 RPC 的模式,具体的我就没有了解了。
点评
评分:⭐⭐☆☆☆
优点:
- 诚实:坦诚说明业务接触少,态度可取
- 架构经验:业务上倾向"减少分布式事务"是好意识(分布式事务成本高)
- 基本概念正确:AT 是强一致、基于 undo log
不足:
- ❌ 未提到三个角色:TC(Transaction Coordinator)+ TM(Transaction Manager)+ RM(Resource Manager)
- ❌ 未描述 AT 模式的核心流程(一阶段/二阶段)
- ❌ 未提到全局锁(Global Lock)——这是 AT 模式解决数据一致性的关键
- ❌ 未提到代理数据源机制(Seata 拦截 SQL 实现)
- ❌ 未提到前镜像/后镜像(before image / after image)
- ❌ 未提到分支事务日志(branch_log)——RM 与 TC 的交互载体
补充:
- 三角色:
- TC:Seata Server,协调全局事务
- TM:业务应用,发起全局事务,调用 TM.start() / commit() / rollback()
- RM:资源管理器,管理分支事务(本质是代理后的 DataSource)
- 核心流程:
- TM 向 TC 申请全局事务 ID(XID)
- 业务调用 RM(即代理后的 DataSource)执行 SQL:
- 先写"前镜像(before image)"
- 再执行业务 SQL
- 再写"后镜像(after image)"+ undo_log(同一本地事务)
- 上报 RM,RM 申请全局锁
- TM 根据业务结果决定 commit 或 rollback:
- 成功:TC 异步删除各 RM 的 undo_log
- 失败:TC 让各 RM 用 undo_log 反向生成回滚 SQL,本地事务回滚
- 关键机制:
- undo_log:Seata 自定义的表,存 before/after image,用于回滚
- 全局锁:行级锁,一阶段提交时获取,二阶段结束释放,防止一阶段提交后数据被其他事务修改
- 代理数据源:业务无感知,Seata 用 JdbcProxy 拦截 SQL 执行
- 与 TCC 的对比:
- AT:框架自动回滚,低侵入,但全局锁会影响并发性能
- TCC:业务显式实现三方法,锁粒度更细,侵入高
完整讲解
第一部分:知识重点剖析
核心考点定位:考察对 Seata AT 模式"自动化分布式事务"机制的精确理解——三角色、两阶段、全局锁、undo log。
知识点拆解:
- 三角色架构
- TC(Transaction Coordinator):Seata Server,协调全局事务,维护全局事务状态
- TM(Transaction Manager):业务应用内的代理,负责开启全局事务、提交或回滚
- RM(Resource Manager):代理 DataSource,管理分支事务,与 TC 通信
- AT 模式两阶段流程
一阶段(本地事务阶段):
业务 SQL 执行:
1. 拦截 SQL,读取业务数据前镜像(before image)
2. 执行业务 SQL
3. 读取业务数据后镜像(after image)
4. 在同一本地事务内:业务 SQL + 写 undo_log(存 before/after image)
5. RM 向 TC 申请全局锁(行级锁)
6. 本地事务提交(业务数据和 undo_log 一起落盘)
二阶段(全局事务阶段):
成功路径:TC 让各 RM 异步删除 undo_log
失败路径:TC 让各 RM 读 undo_log,反向生成回滚 SQL,本地事务回滚
- 全局锁的作用
- 目的:防止一阶段提交后、二阶段提交前,其他事务修改了同一行数据
- 实现:基于行级锁,TC 记录 lock_record 表
- 代价:全局锁存在期间,同一行不能有其他事务修改,影响并发性能
- undo_log 的作用
- Seata 框架自动创建表(业务需手动建表,DDL 见官方文档)
- 存 before/after image(JSON 格式)
- 回滚时框架自动读取 undo_log,生成"反向 SQL"(如
UPDATE t SET col = 'old_value' WHERE id = 1)
- 代理数据源的无感机制
- 业务配置 SeataDataSourceProxy 替换原 DataSource
- 所有 SQL 都被 JdbcProxy 拦截
- 业务代码完全无感知
- 与 2PC / TCC / XA 的对比
| 维度 | 2PC/XA | Seata AT | TCC |
|---|
| 侵入性 | 低 | 低 | 高 |
| 一致性 | 强 | 强 | 强 |
| 阻塞 | 会 | 不阻塞(一阶段后释放本地锁) | 不阻塞 |
| 锁机制 | 行锁(数据库级) | 全局锁(Seata 级) | 业务锁 |
| 回滚方式 | 数据库 redo log | undo_log(业务层) | 业务代码 |
第二部分:考察方向与延伸递进
考察方向:
- 深度:是否能讲出全局锁、undo_log、三角色的具体作用
- 广度:能否对比 AT vs TCC vs XA 的锁机制差异
- 应用:能否识别 AT 模式在高并发场景下的瓶颈(全局锁)
延伸递进面试题:
- "Seata AT 的全局锁,会不会成为性能瓶颈?怎么优化?"
- 要点:全局锁按行加锁,一阶段提交后立即释放本地锁但保留全局锁到二阶段结束;高并发同一行会串行化。优化:缩短事务、批量提交、换 TCC
- "undo_log 表会无限增长吗?怎么清理?"
- 要点:二阶段成功后异步删除;TC 有定时清理任务;如果 TC 故障,undo_log 会滞留,需要人工清理或恢复 TC 后自动清理
- "Seata AT 支持非 MySQL 数据库吗?"
- 要点:支持 PostgreSQL、Oracle、SQL Server 等,但需要各自方言的 undo_log 生成逻辑;MyCAT 等分库分表中间件有特殊适配
第三部分:面试者参考回答(300-600 字口语化)
面试官您好,Seata AT 是 Apache Seata 提供的"自动补偿"模式,核心思想是让业务代码无感知地享受分布式事务,靠框架代理数据源和 undo_log 来实现。 AT 模式有三个角色: - TC(Transaction Coordinator):Seata Server,负责协调全局事务 - TM(Transaction Manager):业务应用里的代理,发起全局事务、决定提交或回滚 - RM(Resource Manager):代理 DataSource,管理分支事务 一阶段是本地事务阶段。业务 SQL 执行时,RM 会拦截这条 SQL,先读取业务数据的"前镜像",然后执行 SQL,再读取"后镜像",最后在同一本地事务里把 undo_log(存 before/after image)和业务数据一起写盘。RM 同时向 TC 申请一个全局锁——这是行级锁,是 AT 模式保证一致性的关键。本地事务提交后,本地锁释放,但全局锁仍然保留,直到二阶段结束。 二阶段是全局事务阶段。如果业务全部成功,TC 让各 RM 异步删除 undo_log,事务结束;如果业务失败,TC 让各 RM 读取 undo_log,反向生成回滚 SQL(比如把数据改回 before image),用本地事务回滚。 这里有个关键点:全局锁是 AT 模式的灵魂。它防止"一阶段提交后、二阶段提交前"其他事务修改同一行数据。代价是高并发场景下,同一行会被串行化,这是 AT 模式的性能瓶颈。如果业务并发很高,可以考虑 TCC——TCC 的锁是业务层自己实现的,粒度更细。 和 2PC/XA 相比,AT 模式的好处是一阶段提交后就释放本地锁,参与者不阻塞;和 TCC 相比,AT 的好处是业务代码无感,框架自动处理。所以 AT 模式适合"订单+库存+支付"这种典型微服务场景,业务改动最小。 不过要提醒一下,生产用 AT 模式前需要做好几件事:建好 undo_log 表、配好 Seata Server 高可用、监控全局锁占用情况。否则全局锁堆积或 TC 故障会导致事务长期悬挂。
面试记录 2026-10-19(第 2 次)
题目:Seata 的 AT 模式的实现原理
难度:medium
标签:arch/distributed/transaction, distributed/xa, distributed/seata, difficulty/medium
评分:⭐⭐☆☆☆(2/5)
练习次数:2
我的回答
seata 的 AT 模式是基于mysql 的 undolog 日志来进行补偿回滚,一阶段先进行sql 执行,然后保存 undolog,如果执行过程中需要回滚,在根据 undolog 来进行回放
点评
优点:
- 抓住核心:基于 undo_log 做补偿回滚
- 知道一阶段执行业务 SQL 并记录 undo_log
不足:
- ❌ 未提三角色:TC / TM / RM
- ❌ 未提全局锁(AT 一致性的关键)
- ❌ 未提 before image / after image
- ❌ 未提代理数据源(业务无感)
- ❌ 未说清二阶段:成功异步删 undo_log、失败反向生成 SQL
- 把 undo_log 说成"MySQL 的",实际是 Seata 自建表
补充:
- 三角色:TC(Seata Server)、TM(发起全局事务)、RM(代理 DataSource)
- 一阶段:拦截 SQL → 读前镜像 → 执行 SQL → 读后镜像 → 同事务写 undo_log → 申请全局锁 → 本地提交
- 二阶段:成功异步删 undo_log;失败读 undo_log 反向生成 SQL 回滚
- 全局锁:防一阶段提交后、二阶段前被其他事务改同一行
ℹ️ 完整讲解见上方首次记录(2026-09-23)