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
# 事務

瀏覽器相容性

另見