Indexeddb 简明教程

IndexedDB - Transactions

事务是一组操作,这些操作要么全部成功,要么全部失败。例如,如果我们通过 UPI 向商家付款,但交易被拒绝,那该笔钱必须退回发送者的帐户。事务维持这种完整性。

以下是如何开启事务的语法:

db.transaction(store[, type]);

此处的存储是我们要在其中执行事务的对象存储。事务的类型有两种:

  1. read-only - 只能读取,它在默认情况下已提供。

  2. read-write - 我们可以只读取和写入数据,但我们不能创建、删除或从对象存储中对其进行更改。

Transaction life cycle

事务是对象存储之间执行任何操作的连接。每个事务都有一个状态,该状态可以是:

  1. active - 当第一次创建事务时。或当一个请求与事务关联时。当它处于该状态时,可以针对事务进行新请求。

  2. inactive - 在事件创建后返回控制后,事务处于该状态。当它处于该状态时,无法针对事务提出任何请求。

  3. committing - 当与某个事务关联的所有请求都完成后,它将尝试提交。在提交状态期间,无法进行任何新请求。

  4. finished - 在一个事务提交或中止之后,它处于完成状态。在完成状态期间,无法进行任何新请求。

The lifetime of a transaction

会形成一个具有范围和模式的事务。当事务生成后,其状态最初是激活的。

  1. 为了开始事务,该实现必须排队一个任务。

  2. 当与事务关联的每个请求被处理后,会触发一个成功或错误事件。在发送事件时,事务状态被设置为激活的,从而允许针对事务进行后续请求。事件分发完成后,事务的状态被设置为非激活的。

  3. 事务可以在完成之前任何时候取消,即使它当前未处于活动状态或尚未开始。

  4. 当针对数据库进行的所有请求都成功时,该实现必须尝试提交事务。

  5. 当提交或撤销事务时,其状态将设置为结束。

Transaction scheduling

当事务可以启动时,有一些限制。

  1. 当没有读或写事务时:a. 在事务 tx 之前建立的 b. 与 tx 有重叠范围的 c. 不处于最终状态的,只读事务 tx 才能开始。

  2. 当没有其他事务时,读/写事务 tx 才能开始 - 在 tx 之前形成的,与 tx 有重叠范围的,或不处于完成状态的。

Upgrade transactions

模式为 " versionchange " 的事务是升级事务。

对象存储和数据库中的索引可以使用升级操作进行创建、重命名和删除。

如果给出的版本大于当前版本,则在打开与数据库的连接后完成运行升级事务的步骤时自动生成升级事务。在 upgradeneeded 事件处理程序中,此事务将处于活动状态。

Committing a transaction

必须完成以下步骤才能提交事务 -

  1. 首先将事务状态设置为提交。

  2. 等到列表中的所有事务请求都已处理。

  3. 如果发生错误,请中止事务。

  4. 如果事务是升级事务,则将数据库升级事务的事务连接设置为 NULL。

  5. 将事务状态更改为完成。

  6. 触发事务的整个事件

  7. 如果事务是升级事务,则将请求的事务设置为 null 并在事务中进行关联的请求。

Syntax

transaction.commit()

尝试提交事务。将允许所有挂起请求完成,但不会接受任何新请求。

如果挂起的请求失败,则事务将中止。成功请求的成功事件仍将触发,但在事件处理程序中抛出异常不会中止事务,调用 preventDefault() 不会阻止事务中止。

Event Handlers

各种事件处理程序属性如下所示

attribute EventHandler onabort;
attribute EventHandler oncomplete;
attribute EventHandler onerror;

Transactions Example

下面给出了一个简单的 JavaScript 程序来演示事务的使用 -

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Document</title>
</head>
<body>
   <script>
      const request = indexedDB.open("botdatabase",1);
      request.onupgradeneeded = function(){
         const db = request.result;
         const store = db.createObjectStore("bots",{ keyPath: "id"});
      }
      request.onsuccess = function(){
         document.write("database opened successfully");
         const db = request.result;
         const transaction=db.transaction("bots","readwrite");
         const store = transaction.objectStore("bots");
         store.add({id: 1, name: "jason",branch: "IT"});
         store.add({id: 2, name: "praneeth",branch: "CSE"});
         store.add({id: 3, name: "palli",branch: "EEE"});
         store.add({id: 4, name: "abdul",branch: "IT"});
         store.put({id: 4, name: "deevana",branch: "CSE"});
         transaction.oncomplete = function(){
            document.write("transaction complete");
            db.close;
         };
      }
   </script>
</body>
</html>

Output

database opened successfully
transaction complete

在这里创建事务,只有在创建事务时才能将数据添加到对象存储中,最终在事务完成后,我们关闭数据库。

Example

以下示例演示了一个事务属性 oncomplete 的用法 -

function student(db, names) {
   let transaction = db.transaction(['names'], 'readwrite');
   let store = transaction.objectStore('names');
   for (let i = 0; i < messages.length; i++) {
      store.add({text: names[i]});
   }
   transaction.oncomplete = function()
   {document.write('transaction complete')};
}

Abort transactions

要中止事务,请按照以下步骤操作 -

  1. 所有与数据库相关的修改都将撤消。

  2. 在升级事务期间,对象存储、索引和版本中的更改同样会还原。

  3. Complete the transaction state.

  4. 如果错误不为 null,则设置事务错误为错误。

  5. 将事务请求列表中每个请求的已处理标志设置为 true。

  6. 设置请求完成标志为 true,并将结果设置为定义。

  7. 如果事务是升级事务,则将与事务的连接关联的升级事务设置为 null。

  8. 使用设置为 true 的 bubbles 属性创建事务中止事件。

  9. 如果事务是升级事务,则假定请求是事务的开放请求。