IDBTransaction
Baseline 广泛可用 *
注意:此功能在 Web Workers 中可用。
IDBTransaction 接口是 IndexedDB API 的一部分,它提供了一个使用事件处理程序属性来对数据库进行的静态、异步事务。所有数据的读取和写入都在事务中进行。您使用 IDBDatabase 来启动事务,使用 IDBTransaction 来设置事务的模式(例如,是 readonly 还是 readwrite),然后访问 IDBObjectStore 来发起请求。您还可以使用 IDBTransaction 对象来中止事务。
事务在创建时启动,而不是在放置第一个请求时启动;例如,考虑以下代码:
const trans1 = db.transaction("foo", "readwrite");
const trans2 = db.transaction("foo", "readwrite");
const objectStore2 = trans2.objectStore("foo");
const objectStore1 = trans1.objectStore("foo");
objectStore2.put("2", "key");
objectStore1.put("1", "key");
代码执行后,对象存储库应包含值 "2",因为 trans2 应该在 trans1 之后运行。
事务在事件循环任务之间在活动和非活动状态之间交替。它在创建它的任务中是活动的,并在请求的 success 或 error 事件处理程序的每个任务中也是活动的。在所有其他任务中,它是非活动的,此时放置请求将失败。如果在事务处于活动状态时没有放置新请求,并且没有其他待处理的请求,事务将自动提交。
事务失败
事务可能由于固定数量的原因而失败,其中(除了用户代理崩溃)所有原因都会触发中止回调。
- 由于无效请求而中止,例如,尝试将相同的键添加两次,或使用具有唯一性约束的相同索引键进行
put()。这会导致请求出错,该错误可能会冒泡到事务错误,从而中止事务。这可以通过在请求的错误事件上使用preventDefault()来阻止。 - 脚本显式调用
abort()。 - 请求的
success/error处理程序中未捕获的异常。 - I/O 错误(例如,磁盘写入失败,或其他操作系统/硬件故障)。
- 配额已满。
- 用户代理崩溃。
Firefox 的持久性保证
请注意,从 Firefox 40 开始,IndexedDB 事务的持久性保证已放宽以提高性能(请参阅 Firefox bug 1112702)。在此之前,在 readwrite 事务中,只有当所有数据都保证已刷新到磁盘时,才会触发 complete 事件。在 Firefox 40+ 中,在指示操作系统写入数据后,但在数据实际刷新到磁盘之前,可能会触发 complete 事件。因此,complete 事件可能比以前更快地传递,但存在一种小概率,即如果在数据刷新到磁盘之前操作系统崩溃或发生系统断电,整个事务将丢失。由于这种灾难性事件很少发生,大多数使用者无需进一步担心。
如果您出于某种原因必须确保持久性(例如,您存储的关键数据无法稍后重新计算),您可以通过使用实验性的(非标准)readwriteflush 模式创建事务来强制事务在传递 complete 事件之前刷新到磁盘(请参阅 IDBDatabase.transaction。
实例属性
IDBTransaction.db只读-
与此事务关联的数据库连接。
IDBTransaction.durability只读-
返回创建事务时使用的持久性提示。
IDBTransaction.error只读-
当事务不成功时,返回一个
DOMException,指示发生的错误类型。如果事务未完成、已完成并成功提交,或通过IDBTransaction.abort()函数中止,则此属性为null。 IDBTransaction.mode只读-
用于隔离事务范围内对象存储的访问模式。默认值为
readonly。 IDBTransaction.objectStoreNames只读-
返回一个
DOMStringList,其中包含与事务关联的IDBObjectStore对象的名称。
实例方法
继承自:EventTarget
IDBTransaction.abort()-
回滚与此事务关联的数据库对象的所有更改。如果此事务已被中止或完成,则此方法将触发一个错误事件。
IDBTransaction.objectStore()-
返回一个
IDBObjectStore对象,该对象代表属于此事务范围的对象存储。 IDBTransaction.commit()-
对于活动事务,提交事务。请注意,通常不需要调用此方法——当所有待处理的请求都已满足且没有新请求时,事务将自动提交。
commit()可用于启动提交过程,而无需等待待处理请求的事件被分派。
事件
使用 addEventListener() 或通过将事件监听器分配给此接口的 oneventname 属性来监听这些事件。
abort-
当
IndexedDB事务被中止时触发的事件。也可以通过onabort属性访问;此事件会冒泡到IDBDatabase。 完成-
事务成功完成后触发的事件。也可以通过
oncomplete属性访问。 error-
当请求返回错误且事件冒泡到连接对象(
IDBDatabase)时触发的事件。也可以通过onerror属性访问。
模式常量
已弃用:此特性不再推荐。虽然某些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除,可能正在删除过程中,或者可能仅为兼容性目的而保留。请避免使用它,如果可能,请更新现有代码;请参阅本页底部的兼容性表格以指导您的决策。请注意,此特性可能随时停止工作。
警告:这些常量不再可用——它们已在 Gecko 25 中移除。您应该直接使用字符串常量。(Firefox bug 888598)
事务可以具有以下三种模式之一
| 常量 | 值 | 描述 |
|---|---|---|
READ_ONLY
|
"readonly" (Chrome 中为 0) | 允许读取数据,但不能更改。 |
READ_WRITE
|
"readwrite" (Chrome 中为 1) | 允许读取和写入数据,可以更改现有数据存储中的数据。 |
VERSION_CHANGE
|
"versionchange" (Chrome 中为 2) | 允许执行任何操作,包括删除和创建对象存储和索引的操作。此模式的事务不能与其他事务并发运行。此模式下的事务称为“升级事务”。 |
即使这些常量现在已弃用,如果您需要向后兼容,仍然可以使用它们。您应该编写防御性代码,以防对象不再可用。
const myIDBTransaction = window.IDBTransaction ||
window.webkitIDBTransaction || { READ_WRITE: "readwrite" };
示例
在以下代码片段中,我们打开数据库的读/写事务,并将一些数据添加到对象存储中。另请注意已附加到事务事件处理程序的函数,用于在成功或失败时报告事务打开的结果。有关完整的可运行示例,请参阅我们的 To-do Notifications 应用(实时查看示例)。
const note = document.getElementById("notifications");
// an instance of a db object for us to store the IDB data in
let db;
// Let us open our database
const DBOpenRequest = window.indexedDB.open("toDoList", 4);
DBOpenRequest.onsuccess = (event) => {
note.appendChild(document.createElement("li")).textContent =
"Database initialized.";
// store the result of opening the database in the db
// variable. This is used a lot below
db = DBOpenRequest.result;
// Add the data to the database
addData();
};
function addData() {
// Create a new object to insert into the IDB
const newItem = [
{
taskTitle: "Walk dog",
hours: 19,
minutes: 30,
day: 24,
month: "December",
year: 2013,
notified: "no",
},
];
// open a read/write db transaction, ready to add data
const transaction = db.transaction(["toDoList"], "readwrite");
// report on the success of opening the transaction
transaction.oncomplete = (event) => {
note.appendChild(document.createElement("li")).textContent =
"Transaction completed: database modification finished.";
};
transaction.onerror = (event) => {
note.appendChild(document.createElement("li")).textContent =
"Transaction not opened due to error. Duplicate items not allowed.";
};
// create an object store on the transaction
const objectStore = transaction.objectStore("toDoList");
// add our newItem object to the object store
const objectStoreRequest = objectStore.add(newItem[0]);
objectStoreRequest.onsuccess = (event) => {
// report the success of the request (this does not mean the item
// has been stored successfully in the DB - for that you need transaction.oncomplete)
note.appendChild(document.createElement("li")).textContent =
"Request successful.";
};
}
规范
| 规范 |
|---|
| Indexed Database API 3.0 # 事务 |
浏览器兼容性
加载中…
另见
- 使用 IndexedDB
- 开始事务:
IDBDatabase - 设置键的范围:
IDBKeyRange - 检索和修改数据:
IDBObjectStore - 使用游标:
IDBCursor - 参考示例:待办事项通知(查看实时示例)。