IndexedDB - 事务

事务是一组操作,要么全部成功,要么全部失败。 例如,如果我们从 UPI 向商家付款并且事务失败,那么资金必须退回到发件人的帐户。 事务可以维护这种完整性。

以下是打开事务的语法 −

db.transaction(store[, type]);

这里的存储是我们要进行事务处理的对象存储。 事务类型有2种 −

  • 只读 − 只能读取,默认给定。

  • 读写 − 我们只能读取和写入数据,但无法从对象存储中创建、删除或更改数据。

事务生命周期

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

  • active − 首次创建事务时。 或者当请求与事务关联时。 当事务处于此状态时,可以对事务发出新请求。

  • inactive − 事务在创建后控制权返回到事件后就处于此状态。 处于此状态时无法针对事务发出任何请求。

  • committing − 一旦与事务关联的所有请求都完成,它就会尝试提交。 在提交状态期间,不能发出新的请求。

  • finished − 事务提交或中止后,它就处于完成状态。 在完成状态期间,不能发出新的请求。

事务的生命周期

形成具有范围和模式的事务。 事务在生成时的状态最初是活动的。

  • 要开始事务,实现必须将任务排队。

  • 当处理与事务连接的每个请求时,将触发成功或错误事件。 发送事件时,事务状态设置为活动状态,允许针对该事务发出后续请求。 事件分派完成后,事务的状态将设置为非活动状态。

  • 事务可以在完成之前随时取消,即使该事务当前未处于活动状态或尚未开始。

  • 当对数据库发出的所有请求都成功时,实现必须尝试提交事务。

  • 当事务提交或中止时,其状态设置为完成。

事务调度

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

  • 当没有读取或写入事务时: 是在事务 tx b 之前建立的。 与 tx c 有重叠范围。 未处于最终状态,可以开始只读事务事务。

  • 当没有其他事务时,读/写事务 tx 可以开始 −

    • 在事务之前形成,
    • 与 tx 有重叠范围,或者
    • 未处于完成状态。

升级事务

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

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

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

提交事务

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

  • 事务状态首先设置为提交。
  • 等待列表中的所有事务请求均已处理完毕。
  • 如果发生错误,则中止事务。
  • 如果事务是升级事务,请将数据库升级事务的事务连接设置为 NULL。
  • 将事务状态更改为完成。
  • 触发事务的整个事件
  • 如果事务是升级事务,请将请求的事务设置为 null 并发出与该事务关联的请求。

语法

transaction.commit()

尝试提交事务。 所有待处理的请求都将被允许完成,但不会接受新的请求。

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

事件处理程序

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

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

事务示例

下面给出了一个简单的 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>

输出

database opened successfully
transaction complete

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

示例

下面的示例展示了事务属性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')};
}

中止事务

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

  • 对数据库的所有与事务相关的修改都将被撤消。

  • 对象存储、索引和版本中的更改同样会在升级事务期间恢复。

  • 完成事务状态。

  • 如果错误不为空,则将事务错误设置为错误。

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

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

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

  • 在事务事件中创建中止,并将 bubbles 属性设置为 true。

  • 如果事务是升级事务,则假设该请求是事务的打开请求。