全部文章
工具笔记

让 AI 复现 SQLITE_BUSY,先量写锁再改配置

等待预算能缓冲短冲突,长写入仍要拆开看。

资料核验2026.11.12 · SQLite · 本地数据库与小型服务

并发保存时偶尔出现 SQLITE_BUSY。把等待时间调成一分钟有时会让日志变安静,用户却要更久才知道失败。先确定是短时间竞争,还是某个事务持锁太久。

交给编码助手的任务

让助手在临时数据库用两个连接构造冲突,一个开启写事务并等待,另一个用固定 busy_timeout 尝试写。要求分别记录持锁时间、等待时间和是否成功,别先改生产超时。

流程示意:连接 A 持锁;B 尝试写入;记录等待和释放

造一个可以重复的竞争场景

连接 A 开写事务但暂不提交,连接 B 尝试写入。用明确的 busy_timeout 观察 B 的等待时间和结果,再让 A 提早提交对照。设置属于连接,多个连接要分别核对。

回到应用里记录事务持续时间,找有没有文件 I/O、网络请求或大批次写入夹在里面。先缩短临界区,再给短竞争留一点等待。

若操作需要重试,确保重试整次事务不会产生重复业务记录。

先准备一个对照样例

同一测试库分别运行「A 持锁 50ms,B 等 200ms」和「A 持锁 300ms,B 等 100ms」。时间是示例参数,实际记录以本地调度为准。看错误是否在预算外出现,再对照业务事务发生在哪段。

用这些结果验收

  • 短持锁能在预算内完成。
  • 超过预算时出现预期忙错误。
  • 应用把网络等待移出事务后,新的持锁数据能和基线比较。

审查时容易漏掉什么

调长等待有时能掩盖问题,却会拉高响应时间。先定位是哪条事务占锁,再决定分批、缩短事务还是重试。重试前验证整次操作可安全重复。

观察时把「等锁」和「持锁」分别记录,两个时间不是同一概念。调大连接等待只影响失败出现得多快,仍要看锁持有者执行了什么。确认重试从干净事务开始,并限制总等待不会压住后续请求。

资料来源