P83 什么是分布式事务,常见的实现方案又有哪些
面试题:跨服务/跨库的事务怎么保证?分布式事务有哪些方案?
1. 问题背景
单库事务靠数据库 ACID;微服务下一次操作涉及多个服务、多个库,本地事务管不住别人,需要分布式事务方案。
2. 常见方案
① 2PC / XA(强一致)
两阶段提交:
text
准备阶段:协调者问所有参与者"能提交吗?"(各自执行但先不提交)
提交阶段:全部准备成功 → 全局提交;有失败 → 全局回滚- 代表:Seata AT 模式的 XA 分支、数据库 XA;
- 优点:强一致;缺点:同步阻塞、协调者单点、性能差,高并发场景不友好。
② TCC(补偿事务)
text
Try(预留资源)→ Confirm(确认执行)→ Cancel(补偿回滚)- 代表:Seata TCC、手工实现;
- 优点:性能好、灵活;缺点:侵入业务,每个操作要写 Try/Confirm/Cancel 三套逻辑;
- 适用:资金类、强一致要求高但性能也重要的场景。
③ 本地消息表(最终一致)
text
业务操作 + 消息表写入在同一个本地事务
定时任务扫描消息表 → 发送 MQ → 消费方处理 → 确认删除消息- 优点:实现简单可靠;缺点:消息表与业务耦合、有扫描延迟。
④ MQ 事务消息(最终一致,推荐)
RocketMQ 事务消息:
text
① 发送 half 消息(半消息,消费者不可见)
② 执行本地事务
③ 本地事务成功 → commit(消费方可见);失败 → rollback
④ 超时未决 → 回查本地事务结果- 优点:异步解耦、可靠;缺点:依赖 MQ 的事务消息能力。
⑤ 最大努力通知 / 对账补偿
定时对账 + 补偿任务,兜底保证最终一致。
3. 方案选型
| 场景 | 方案 |
|---|---|
| 强一致、低频 | 2PC/Seata AT |
| 高并发资金操作 | TCC |
| 异步解耦、最终一致 | MQ 事务消息 / 本地消息表 |
| 兜底 | 对账补偿 |
4. 加分点
- 说"能不用分布式事务就不用":通过本地事务 + 消息解耦、最终一致性设计规避;
- 提到 Seata 的 AT/TCC/SAGA/XA 四种模式;
- 追问"幂等":分布式事务的补偿和重试都要求消费/操作幂等;
- 提到 Saga(长事务、补偿编排)适合流程长、允许中间状态的业务。
一句话总结
分布式事务方案:强一致用 2PC/XA,高并发资金用 TCC,最终一致用 MQ 事务消息/本地消息表 + 对账补偿;核心原则是能最终一致就别强一致,所有方案都要配合幂等与补偿。