IndexedDB事务默认自动回滚:任一请求失败即触发onabort并撤销所有操作,无需手动rollback;仅在request.onerror中调用preventDefault可阻止中止,但需自行处理错误。

IndexedDB 的事务本身不提供手动回滚 API,但它的原子性和错误传播机制天然支持“失败即回滚”——只要你不干预,默认就是强一致性保障。
事务失败自动回滚是默认行为
在 readwrite 或 versionchange 事务中,任意一个请求(如 put、add、delete)抛出未被捕获的错误(例如 ConstraintError、AbortError、QuotaExceededError),浏览器会立即触发 transaction.onabort,并中止整个事务。此时所有已执行但未提交的操作全部失效,数据库状态退回事务开始前——这等价于自动回滚。
- 不需要写 rollback() 或类似语句,IDB 没有这个方法
- 也不需要手动清空缓存或重置状态,引擎层已保证隔离性
- 页面关闭、刷新或进程终止时,未完成事务也会被静默回滚
防止误中断:用 preventDefault 控制错误传播
有时你希望某个错误(比如插入重复 key)不导致整笔事务失败,而是跳过或修正后继续执行。这时必须在对应请求的 onerror 中调用 event.preventDefault():
- 只阻止中止,不修复错误;业务逻辑需自行处理(如改 key、跳过、重试)
- 漏掉 preventDefault 就等于放任事务崩溃,哪怕后续还有 put/add 也不会执行
- 注意:preventDefault 对 transaction.onerror 无效,只对 request.onerror 生效
确保关键操作不被遗漏
静默失败常见于“日志没写但主数据写了”,本质是事务提前关闭。原因通常是:
- 在 onsuccess 回调里用了 fetch / setTimeout / Promise.then 发起新请求——这些异步操作不延长事务生命周期
- 多个 IDB 请求没串在同一个事务上下文中(比如各自 new transaction)
- 读写混用同一 objectStore 且并发高,后启动的事务排队超时
解决办法:所有相关操作(get + put + add)必须在同一个事务内完成,且都在原生 IDB 请求链中发起(例如在 request.onsuccess 里直接调用 objectStore.add())。
主动监控事务结果更可靠
依赖自动回滚还不够,建议显式监听两个事件:
- transaction.oncomplete:确认成功提交,可触发 UI 更新或清理
- transaction.onerror:捕获未被 preventDefault 拦截的错误,做统一上报或降级处理
注意:onerror 是事务级的兜底,不是 request 级的;它不会告诉你哪个请求出错,所以关键请求仍要单独配 onerror 做精细化控制。











