indexeddb事务天然支持原子性批量写入:同一事务中所有操作要么全部成功,要么全部失败。事务需显式创建并指定作用域和模式,作用域决定可访问的objectstore,模式为“readwrite”才允许写操作;批量写入必须在同一个事务内完成,通过同一transaction下的objectstore方法执行;事务默认自动提交,可通过oncomplete监听成功、onerror捕获失败或abort主动回滚;避免为每次写操作新建事务、缓存失效store实例或跨事务异步写入。

IndexedDB 通过事务(transaction)天然支持原子性批量写入:同一事务中所有操作要么全部成功,要么全部失败,不会出现中间状态。
事务的创建与作用域控制
事务必须在打开数据库后显式创建,且需指定作用域(即影响哪些 objectStore)和模式(只读或读写):
- 作用域决定事务能访问哪些 objectStore,未声明的 store 无法操作
- 模式为
"readwrite"时才能执行 add、put、delete 等写操作 - 事务一旦开始,其作用域和模式不可更改
示例:
const tx = db.transaction(['users', 'logs'], 'readwrite');批量写入必须在同一个事务内完成
多个写操作(如多次 put 或 add)需调用同一个 transaction 下的 objectStore 方法,不能跨事务或跨 transaction 实例:
- 每个
tx.objectStore('name')返回的是该事务上下文中的 store 实例 - 所有请求(request)都绑定到该事务,事务结束前它们共享同一个原子性边界
- 任意一个请求失败(如主键冲突、存储空间不足),整个事务自动中止,已执行的写入全部回滚
正确写法:
const store = tx.objectStore('users');store.put({id: 1, name: 'Alice'});
store.put({id: 2, name: 'Bob'});
store.add({id: 3, name: 'Charlie'});
主动控制事务生命周期
事务不会自动提交,它的完成取决于所有请求是否成功以及是否显式调用 commit()(实际极少手动调用):
- 默认行为:当所有请求完成且无错误时,事务自动提交
- 监听
transaction.oncomplete可确认批量写入成功 - 监听
transaction.onerror或任一 request 的onerror可捕获失败并做统一处理 - 调用
transaction.abort()可主动中止,触发回滚(例如校验不通过时)
避免常见陷阱
原子性失效往往源于误用事务边界:
- 不要为每个写操作新建一个 transaction——这会失去原子性保障
- 不要在事务外缓存 store 实例(如
const s = db.transaction(...).objectStore(...)),事务结束后该实例失效 - 异步操作(如 fetch 后再写入)需确保所有写入都在同一事务的回调链内发起,否则可能跨事务
- 注意事务的自动关闭机制:若没有活跃请求且无未完成事件监听,事务可能提前关闭
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











