在 浏览器 IndexedDB 简明教程 ( 七 ) - 数据库 ( IDBDatabase ) 方法 中我们故意漏讲了一个方法 transaction()
IDBDatabase.transaction()
IndexedDB 规定 「 在对新数据库做任何事情之前,需要开始一个事务, 事务中需要指定该事务跨越哪些存储对象 ( objectStore ) 」
对于事务,一个简单的理解就是,一个事务里的操作,要么全部执行成功,要么全部执行失败
IndexedDB 提供了 IDBDatabase.transaction()
方法用于开启是一个事务,并且返回一个 IDBTransaction
对象
该方法的原型是
IDBDatabase.transaction(storeName, [mode])
参数 | 说明 |
---|---|
storeName | 必填,用于指定事务中需要操作到的存储对象,如果只有一个存储对象,可以直接写存储对象名,如果有多个存储对象,那么需要把它们封装成一个列表 ["user","city"] |
mode | 可选,用于指定事务的类型,可选的值有:readonly ( 默认 ) 或者 readwrite |
IDBTransaction 对象
IDBTransaction
表示一个事务对象,我们使用 IDBDatabase.transaction()
方法在数据库上创建一个事务,实际上是在指定事务的它的范围 ( 例如希望访问哪一个存储对象 ),并确定希望的访问类型 ( 只读或读写 )
IDBTransaction
对象提供了以下方法和属性
IDBTransaction 属性
属性 | 说明 |
---|---|
IDBTransaction.db | 只读,返回与此事务对象相关联的数据库连接 |
IDBTransaction.mode | 只读,返回事务模式 readonly / readwrite / versionChange |
IDBTransaction.error | 返回一个错误 |
IDBTransaction 属性
方法 | 描述 |
---|---|
IDBTransaction.abort() | 放弃本次连接的 transaction 的所有修改,如果当前的 transaction 处于回滚完毕或完成状态,则会抛出一个错误事件 |
IDBTransaction.objectStore(name) | 获取对象存储空间 |
IDBTransaction.onabort = function() | 事务终止回调事件 |
IDBTransaction.oncomplete = function() | IDBTransaction 接口处理完成时回调事件 |
IDBTransaction.onerror = function() | IDBTransaction 发生错误时的回调事件 |
如果对比其它数据库中的事务,会发现一个有趣的问题,就是没有提交事务的方法。IndexedDB 模式是开启事务的,也默认会自动提交事务,如果中途需要终止事务,则直接调用 IDBTransaction.abort()
方法即可
范例
例如,下面的代码在存储对象 city
上开启一个默认事务 ( 只读 )
let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; db.transaction( ['city'] ); }; req.onupgradeneeded = function (event) { console.log('升级成功'); db = event.target.result; db.createObjectStore('city',{keyPath:'city_id'}); }
需要注意的是,开启事务的存储对象必须存在,例如下面的代码,是会报错的
var db; //先删除 window.indexedDB.deleteDatabase('demo') var req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; db.transaction( ['city'] ); };
输出结果如下
打开数据库成功 Uncaught DOMException: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.
联想
大家有没有发现,开启事务需要存储对象已经存在,而创建存储对象或删除存储对象的操作又需要在一个 「 版本变更 」 的事务里,那么,其实,就是否说明了这两个方法只能在 onupgradeneeded
事件回调里使用?