indexeddb事务通过自动生命周期管理和作用域隔离保障原子性与一致性:创建即启动,成功完成则隐式提交,出错或abort则回滚;readonly允许多并发,readwrite按object store交集串行化;需显式preventdefault()阻止中止,并监听oncomplete/onerror/onabort确保可控。

IndexedDB 的事务(Transaction)是保证数据操作原子性和一致性的核心机制,它不是靠开发者手动提交或回滚的“传统事务”,而是通过自动生命周期管理和作用域隔离来实现一致性。
事务自动管理:打开即开始,无显式 commit
IndexedDB 中事务在创建时立即启动,所有操作必须在事务活跃期内完成。事务不会自动 commit,而是根据以下规则决定最终结果:
- 若所有请求成功完成,且事务未被中止或超时,事务自然完成(相当于隐式 commit)
- 若任意请求触发 error 事件且未被阻止(例如未调用 event.preventDefault()),事务会自动中止(abort)
- 若手动调用 transaction.abort(),所有已排队但未执行的操作会被丢弃
- 事务对象一旦进入 inactive 或 finished 状态,就不可再发起新请求
事务作用域决定读写权限与并发行为
创建事务时需指定作用域(Object Store 名称数组)和模式(readonly 或 readwrite),这直接影响一致性保障方式:
- readonly:允许多个并发只读事务同时访问同一 object store,互不阻塞
- readwrite:对指定 object store 加排他锁,后续同 scope 的 readwrite 事务需等待前一个完成,避免写冲突
- 多个不同 object store 的 readwrite 事务可并行,但若存在交集(如都包含 "users"),则按交集部分串行化
例如:db.transaction(["users", "logs"], "readwrite") 会同时锁定 users 和 logs;而另一个仅操作 "orders" 的事务可并行执行。
错误处理必须显式干预才能维持事务活性
IndexedDB 默认在请求出错时中止整个事务。若想让事务继续(比如跳过某条失败记录),需在 request 的 error 事件中调用 event.preventDefault():
- 不阻止默认行为 → 事务 abort,所有变更丢失
- 调用 preventDefault() → 错误被静默忽略,事务保持 active,后续操作仍可执行
注意:preventDefault() 只阻止事务中止,不改变请求本身的失败状态,你需要自行判断是否重试或降级处理。
事务生命周期需主动监听,避免“幽灵操作”
事务没有超时机制,但存在隐式失效风险。务必监听关键事件确保逻辑可控:
- transaction.oncomplete:事务成功完成,适合做收尾清理或通知
- transaction.onerror:事务因未捕获错误而中止,可用于统一日志或回退提示
- transaction.onabort:事务被显式 abort 或自动中止,适合释放资源或重试调度
- 避免在事务 inactive 后调用 objectStore() —— 会抛出 InvalidStateError
常见陷阱:在 onsuccess 回调里发起新请求,但未确认事务仍 active;正确做法是始终从 transaction 对象获取 store,或使用 Promise 封装确保时序。
不复杂但容易忽略:事务一致性不依赖你“做什么”,而取决于你“怎么组织作用域、如何响应错误、何时发起操作”。只要遵循作用域最小化、错误有兜底、操作不过期这三条,就能稳定获得 ACID 中的 Atomicity 和 Consistency 保证。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











