Python 现代开发学习笔记

18-05 复现写入后的失败

本章题解 · 全部练习

题目

在业务提交之后制造失败,关闭并重新打开检查点后重试。核对最终计划只有一行,再试同一操作编号携带另一份内容,保留对应失败用例。

推导与做法

第一次保存已经提交 plans,但节点返回前抛错,因此检查点仍指向待完成的 save。重开 SQLite saver 后,从旧状态重试,operation_id 必须保持不变。

PlanStore 的唯一键让第二次执行读取原行,不再插入。题解分别检查中断后和重试后的行数都为 1,再用同一编号提交不同分钟数,得到 ValueError。只有“没有重复行”还不足以证明两个不同动作没有被错误合并。

过程图

%% 每个节点保留输入、执行位置或执行后的实际状态。 flowchart TD A["save进入:检查点保留operation_id=op1"] A --> B["业务INSERT提交,plans已有1行"] B --> C["节点返回前故障,图仍待save"] C --> D["关闭连接,再打开旧检查点"] D --> E["重试save:仍使用op1和原内容"] E --> F["唯一键命中已有行,读取原id"] F --> G["图变为saved,plans仍为1行"] E --> H["若同op1换成另一分钟数"] H --> I["内容比较失败,拒绝覆盖原计划"] classDef default fill:#EEF0FB,stroke:#4657B5,color:#24324A linkStyle default stroke:#4657B5

实现与运行

查看带注释实现。本题与相关处理函数放在同一章节代码文件中;启动工具负责定位相邻项目和选择题号。

在配套目录的 LangChain与AgentRuntime/study_agent 中运行。先按项目 README 执行 uv sync --locked。本章先执行 uv sync --locked --all-extras。18-06 还需执行 uv pip install -e "../../FastAPI/api_project",接入前面 API 声明的依赖;之后使用 --no-sync 保留这份组合环境。

# 使用项目解释器运行本题,题号决定执行哪一组演示。
uv run --no-sync python "../../学习索引/参考实现/代码/ch18.py" 18-05

程序按题号输出处理后的值、查询结果或状态。先和前面的手算比较,再修改一项输入重跑。

查看本题运行结果
# 与上面的手算状态和题目数值逐项比较。
{
  "rows_after_crash": 1,
  "rows_after_retry": 1,
  "status": "saved",
  "changed_payload_rejected": true
}

笔记正文与全部题解 · Ctrl / ⌘ K