04让协作过程经得住中断 · 第 13 章
总进度 13 / 15

12|服务重启以后,怎样知道做到哪一步

如果任务只保存在内存中,进程一停,进度也就没了。这一节打开项目使用的 SQLite 存储代码,模拟一次未完成执行,再观察重启后的状态恢复。

2026-09-28约 7 分钟28 行代码难度 ★★★

如果想获取全套课程资料,请关注微信公众号 「AI面包君」,回复 「课程资料」 即可领取。

如果任务只保存在内存中,进程一停,进度也就没了。这一节打开项目使用的 SQLite 存储代码,模拟一次未完成执行,再观察重启后的状态恢复。

我们要实现的是“记住进度,交给人决定是否继续”。它不等于所有外部操作都能无损接着跑,尤其是已经发出的远程请求,需要另外确认。

保存进度与恢复执行,是两件相连的事

游戏里存档的用途不是让你从第一关再打一遍,而是告诉你哪些关已经完成、哪些奖励已经拿过。工作台也要保存任务状态、产物以及步骤之间的关系,重启后才知道下一步在哪里。

像素插图:保存状态与产物,重启后核对已完成步骤,再继续

但业务系统比游戏多一个麻烦:它可能已经向外部系统发了消息或创建了工单。如果刚创建成功就断电,而本地还没记下成功状态,简单重跑可能生成第二张工单。持久化解决“进度记在哪里”,幂等设计解决“重复请求会不会重复生效”,两者不能互相替代。

学习本节时,可以拿三个问题检查任何恢复方案:已经完成的步骤能否被识别?已产出的内容能否取回来?外部动作处于不确定状态时,是先查询核对还是直接重做?先说清这三点,再看数据库代码,就容易看出每个字段为什么存在。

1. 用临时数据库做恢复实验

在项目根目录运行:

.\.venv\Scripts\python.exe labs.py 12

实验先保存一项任务,把某一步标为执行中,再重新打开同一个临时数据库并调用恢复函数。预期出现 interrupted,随后实验主动继续并走完流程。

重新打开数据库后识别 interrupted,再人工恢复执行

图中内容来自课程实验的实际输出,按阅读宽度排成终端记录;任务编号和耗时会随每次运行变化。

这个实验模拟的是“数据库留下未结束状态”,没有替你强行终止正在使用的网页服务。两者都用同一个恢复函数,但要区分模拟动作与真实崩溃测试。

进程里的记忆与磁盘里的记录

在 Python 中写 jobs = {},再把任务放进去,程序运行时当然能查到。但它像临时记在白板上的内容:进程退出以后,新进程创建的是另一个空字典,不会自动继承之前的变量。

SQLite 把记录保存在文件中。重新启动程序,再打开同一个数据库文件,才能读回原任务。这里“同一个”很重要:如果工作目录或数据库配置变了,程序可能打开另一份空文件,你会以为历史丢失,其实查错了位置。

当前工作台使用项目 data 目录下的 workbench.db,位置由配置代码确定。终端实验则创建临时数据库,实验结束后清理,不是永久历史入口。理解这两种存储路径以后,就不会把“网页没有实验任务”误判为保存失败。

2. 任务和事件分别怎样保存

试读到这里 · 后续内容已封存

关注公众号,继续把这章学完

在「AI面包君」发送关键词「学习AI」拿到口令。验证一次,这个浏览器就能继续阅读全部课程。