浏览器工程

IndexedDB 事务边界:分块落盘与进度为何会不一致

说明事务自动提交、异步间隙、对象仓库原子性和崩溃恢复,保证文件块、区间 manifest 与任务状态不会互相撒谎。

把它做成生产功能之前,需要先拆开协议事实、产品承诺和运行成本,三者混在一起很容易得到错误结论。 IndexedDB 事务在事件循环没有待处理请求时可能自动提交。把网络 await 放在读写中间,常会得到 TransactionInactiveError;把块和 manifest 分开事务又会留下只更新一边的崩溃窗口。

浏览器能力由版本、权限、页面可见性和设备策略共同决定。实现需要能力探测与可解释降级,不能把某一台开发机上的 API 存在当成产品契约。

落地方案的关键部件

落地时要把关键选择变成稳定契约:输入如何校验、状态由谁推进、资源何时释放、旧版本如何降级。只有这样,后续优化才不会改变原有语义。

  • 网络读取在事务外完成,事务内只做同步发起的块写入、区间合并和状态更新。
  • 以任务和块索引作为幂等键,重复到达不会增加已接收字节。
  • 升级 schema 用明确版本迁移,失败时保留旧数据并给出恢复或清理路径。

持久化可信度来自同一事务里的数据与索引,而不是 UI 记住的百分比。先定义崩溃不变量,再安排 IndexedDB 请求。

别让错误假设进入生产

生产问题往往发生在两个正确动作同时到达时。需要逐条检查迟到消息、重复执行、资源耗尽和版本交叉,而不是只补当前堆栈显示的那一行。

  • 先更新 manifest 再写块,存储配额失败后刷新会跳过不存在的数据。
  • 长事务等待网络阻塞其他任务,浏览器随后中止并回滚全部写入。
  • 进度来自内存计数而非已提交记录,崩溃后数字倒退且无法解释。

发布闸门应该检查什么

验证时同时观察两端状态、持久化记录和可观测指标。单看某个按钮或一次接口响应,无法证明整个闭环成立。

  1. 在块写、manifest 合并和 commit 前后逐点终止页面,重启后核对不变量。
  2. 重复、乱序和并发写同一块,断言存储唯一且进度只计算一次。
  3. 耗尽配额并触发 schema 升级失败,确认错误可操作且旧任务不被破坏。

完成并不等于主路径跑通,而是每个终态都能对账、每个自动动作都受用户意图约束、每个成本都有明确上限。

把方法变成一次真实连接

打开 uCopy,让两台设备在浏览器里安全连接并开始传输。

开始免费使用