外观
Checkpoint、业务持久化与任务队列
核心答案:三者保存的事实不同。 Checkpoint 回答流程运行到哪里;业务库回答教材是什么、哪个版本已审核;任务队列回答哪项工作待执行、谁持有执行权、何时重试。即使都存进 PostgreSQL,也不自动成为同一事务。
数据责任
| 数据 | 主要归属 | 恢复时的用途 |
|---|---|---|
| 当前节点、图状态、人工暂停点 | Checkpoint | 恢复线程中的流程 |
| 内容、版本、审核人及结论 | 业务表 | 确定可交付的事实 |
| 素材任务、租约、尝试次数 | 任务表 | 重新派发工作 |
| 外部请求 ID、结果路径与校验值 | 调用与素材记录 | 核对副作用是否发生 |
LangGraph 的持久化说明区分线程 Checkpointer 与跨线程 Store;应用自己的业务表不必因此改写成框架 Store。
最小例子:恢复不能只看图
python
checkpoint = {"next": "make_audio", "version": 2}
assets = {(2, "audio"): {"status": "ready", "sha256": "sample"}}
key = (checkpoint["version"], "audio")
next_action = "reuse" if key in assets else "enqueue"
assert next_action == "reuse"这是数据核对的演示样例,sample 不是真实文件哈希。若进程在音频成功后、Checkpoint 写入前崩溃,恢复节点必须先查业务结果;否则可能重复付费生成。
教材系统的安排
本项目把流程、教材版本、后台任务分层存储。任务以短事务领取并写租约,耗时外部调用在事务外执行;完成时再校验任务归属和目标版本。租约到期表示旧 worker 的执行资格过期,不证明外部调用未成功。
PostgreSQL SKIP LOCKED 可用于多个消费者领取队列表记录,但它提供的视图不适合一般业务查询,官方 SELECT 文档明确描述了这一取舍。任务表与业务更新在同一数据库内可使用事务;跨外部消息系统时则可评估 outbox。
图恢复时还要考虑节点重入、线程 ID 稳定性和代码版本变化。只使用内存 Checkpointer 无法承诺进程重启后的恢复。完整链路见系统架构。
自测与排障
分别模拟“任务还在排队”“素材文件已生成但状态未提交”“Checkpoint 早于业务版本”三种情况,说明应查询哪份记录、允许自动重试还是转人工核对。验收重点是能说明各层证据不一致时谁是依据。
常见误区包括把业务对象全部塞进图状态、认为数据库事务能撤销远程 API、或认为 Checkpoint 能保证外部副作用恰好一次。
官方资料与版本边界
- LangGraph Persistence:线程状态与 Store。
- PostgreSQL SELECT:行锁与
SKIP LOCKED。 - AWS Transactional outbox:业务写入与事件发送的双写问题。
核验日期:2026-11-03。示例只讲恢复决策;实际 Checkpointer 类型、表结构、租约策略及断点行为以交付代码和测试证据为准。