Web Locks API 仅提供跨上下文互斥执行协调,不操作存储也不保障原子性;必须与 IndexedDB 等配合使用,锁名需带业务粒度标识(如 storage-note-${noteId}),mode 必须设为 'exclusive',ifAvailable 应启用以防卡死,回调须返回 Promise,锁内仅包“读–改–写”最小段,Safari 不支持需服务端幂等兜底。

Web Locks API 不能实现“本地存储资源的原子化独占访问”这种笼统说法——它本身不操作任何存储,也不提供原子性保障;它只提供跨标签页、Worker 的**互斥执行协调能力**,必须与具体存储机制(如 IndexedDB、localStorage)配合使用,且需严格遵循语义和边界限制。
锁名必须带业务粒度标识,避免全局误阻塞
用固定字符串如 'storage' 或 'user-data' 作锁名,会导致所有用户、所有数据项共用一把锁,严重降低并发度。正确做法是将锁名绑定到具体资源实例:
-
按数据实体隔离:例如
`storage-note-${noteId}`、`storage-cart-${userId}` -
确保 URL-safe:避免空格、斜杠、控制字符;可对用户输入做
encodeURIComponent()清理,但非强制 - 长度合理控制:建议 ≤64 字符,过长可能影响内部哈希性能,且无实际语义增益
必须显式指定 mode 和 ifAvailable,否则锁形同虚设
默认行为在旧版浏览器中可能 fallback 到 shared 模式,而 shared 锁无法阻止并发写入——这会让开发者误以为已加锁,实则毫无保护。
-
写操作一律用
mode: 'exclusive':这是实现“独占访问”的唯一有效模式 -
高交互场景必设
ifAvailable: true:防止 UI 卡死;若锁不可用,应降级提示(如“其他窗口正在编辑”),而非无限等待 -
回调必须返回 Promise:同步返回(如
return 'ok')会导致锁立即释放,失去保护意义
锁内只包裹“读–改–写”最小原子段,严禁副作用
锁持有时间越长,排队越严重,用户体验越差。Web Locks 不是事务管理器,它只负责“谁能在什么时候跑这段代码”,不负责“这段代码是否安全”。
-
仅包存储操作核心链:例如从 IndexedDB 读旧值 → 计算新值 →
put()写入 →await tx.done - 移出锁外的操作包括:网络请求、加密计算、DOM 渲染、日志上报、通知弹窗等
- localStorage 场景要格外谨慎:它本身是同步阻塞 API,无法被锁“插入时序控制”;Web Locks 对其只有逻辑协调作用,强一致性仍需服务端幂等兜底
Safari 不支持是事实,fallback 必须设计为功能可用而非仅降级提示
iOS 17.5 / macOS 14.5 中 Safari 仍未实现 Web Locks API。仅靠 if ('locks' in navigator) 跳过逻辑,等于在 Safari 中完全放弃互斥保障。
-
底线方案是服务端幂等:每个前端写请求附带唯一
requestId,后端校验是否已处理,避免重复生效 -
轻量客户端 fallback 可用 localStorage + storage 事件模拟:写前存
lock:cart-123:timestamp,监听到冲突则提示,但需明确告知用户“此为弱提示,非强锁定” - 绝不依赖锁来保证数据最终一致:Web Locks 是客户端优化手段,不是一致性基础设施

















