一句话定义:补偿事务(Saga)是把一个长流程拆成若干步,每一步都预先配好一个"反向操作",一旦某步失败,就按相反的顺序把前面已经完成的步骤逐个撤销,让整件事在业务上回到"没做成"的状态。
为什么不能直接回滚
数据库里的事务(Transaction)可以回滚,是因为所有操作都在同一个库里,引擎替你按原样抹掉。但 Agent 干的活往往跨系统:读邮件、写草稿、建日历事件、发 Slack 通知、更新 CRM。这些操作一旦发出去,就收不回来了——邮件已经躺在别人收件箱里,日历邀请已经推送出去。
打个比方:你找人办一场婚礼,先订了酒店、再订了车队、最后订花。花店说那天没花了,整件事办不成。你没法"让时间倒流",只能挨个打电话:退车队、退酒店。这一串"退订电话",就是补偿事务。
补偿不等于回滚
这是最容易混淆的一点。回滚是"假装没发生过",补偿是"再发一笔反向操作"。银行转账扣了 100 块,回滚是账上从未出现这笔记录;补偿是再转 100 块回来。两者财务结果一样,流水的痕迹不一样。所以 Saga 保证的是最终一致,不是原子性。
Agent 场景怎么落地
假设一个 Agent 要完成"起草周报并发给团队":
1. 读取数据源 → 无副作用,不用补偿
2. 写入草稿文件 → 补偿:删除草稿
3. 创建日历评审事件 → 补偿:删除事件
4. 发 Slack 通知 → 补偿:发一条"上条作废"
5. 更新 CRM
第 4 步失败,就倒着走:删日历事件、删草稿。CRM 没动过,不用管。关键是每一步完成后都要留下"补偿句柄"——订单号、事件 ID、消息 ID,否则你连撤哪个都不知道。
| 数据库事务 | 两阶段提交(2PC) | Saga | |
|---|---|---|---|
| 范围 | 单个库 | 多个库,同步 | 跨服务、跨系统,长流程 |
| 一致性 | 强一致 | 强一致 | 最终一致 |
| 是否持锁 | 短暂 | 全程持锁 | 不持锁 |
| 失败处理 | 自动回滚 | 全体回滚 | 反向补偿 |
几个工程上必须注意的点
- 幂等(AI 词典:Idempotency">Idempotency):补偿本身可能被重试,删两次不能报错。
- 补偿也会失败:所以要有重试 + 人工兜底队列(Dead Letter Queue),不能假装它一定成功。
- 有些步骤不可补偿:邮件发出去了就是发出去了。对策是设"可撤销窗口",比如延迟 30 秒发送,窗口内还能拦下来。
- 顺序必须反着来:先补偿最后完成的步骤,因为前面的步骤可能依赖它。
对从业者的意义
写 Agent 工具(Tool)时,每个有副作用的工具都该问一句:"它的 undo 是什么?"没有 undo 的工具,要么拆小,要么加确认。宁可留下"已知的脏数据",也别留下"不知道脏在哪的数据"。
对普通人的意义
AI 助手说"我把日程改了,不过刚才是误操作,已经撤回",或者电商给你退款而不是取消扣款——背后跑的就是这套补偿逻辑。至于具体产品的撤销时限和范围,各家不一样,以官方页面为准。
