IDBTransaction

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

注意:此功能在 Web Workers 中可用。

IDBTransaction 接口是 IndexedDB API 的一部分,它提供了一个使用事件处理程序属性来对数据库进行的静态、异步事务。所有数据的读取和写入都在事务中进行。您使用 IDBDatabase 来启动事务,使用 IDBTransaction 来设置事务的模式(例如,是 readonly 还是 readwrite),然后访问 IDBObjectStore 来发起请求。您还可以使用 IDBTransaction 对象来中止事务。

EventTarget IDBTransaction

事务在创建时启动,而不是在放置第一个请求时启动;例如,考虑以下代码:

js
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 之后运行。

事务在事件循环任务之间在活动非活动状态之间交替。它在创建它的任务中是活动的,并在请求的 successerror 事件处理程序的每个任务中也是活动的。在所有其他任务中,它是非活动的,此时放置请求将失败。如果在事务处于活动状态时没有放置新请求,并且没有其他待处理的请求,事务将自动提交。

事务失败

事务可能由于固定数量的原因而失败,其中(除了用户代理崩溃)所有原因都会触发中止回调。

  • 由于无效请求而中止,例如,尝试将相同的键添加两次,或使用具有唯一性约束的相同索引键进行 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) 允许执行任何操作,包括删除和创建对象存储和索引的操作。此模式的事务不能与其他事务并发运行。此模式下的事务称为“升级事务”。

即使这些常量现在已弃用,如果您需要向后兼容,仍然可以使用它们。您应该编写防御性代码,以防对象不再可用。

js
const myIDBTransaction = window.IDBTransaction ||
  window.webkitIDBTransaction || { READ_WRITE: "readwrite" };

示例

在以下代码片段中,我们打开数据库的读/写事务,并将一些数据添加到对象存储中。另请注意已附加到事务事件处理程序的函数,用于在成功或失败时报告事务打开的结果。有关完整的可运行示例,请参阅我们的 To-do Notifications 应用(实时查看示例)。

js
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
# 事务

浏览器兼容性

另见