微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

开始Dexie交易时的TransactionInactiveError

如何解决开始Dexie交易时的TransactionInactiveError

我有一个服务功能(使用打字稿4.0.2 + webpack 4.44.1 + dexie 3.0.2),可将jsonfile同步到我的Dexie IndexedDB数据库。但是,一旦我开始数据库事务,就会收到错误消息:

Unhandled rejection: TransactionInactiveError: Transaction has already completed or Failed
./node_modules/dexie/dist/dexie.mjs/Transaction.prototype._promise@http://localhost:9000/dist/bundle.js:4876:30
./node_modules/dexie/dist/dexie.mjs/Dexie.prototype._transaction@http://localhost:9000/dist/bundle.js:6488:35
./node_modules/dexie/dist/dexie.mjs/Dexie.prototype.transaction@http://localhost:9000/dist/bundle.js:6438:34
updateEDSMSector/<@http://localhost:9000/dist/bundle.js:169098:26
...
...

错误仅在console.log('extracted json',json);语句之后出现(但是下一个console.log永远不会发生)。我完全不知道我在做什么错。我希望任何人都可以指出如何调试问题。

  static async updateEDSMSector(sector_number: number[],db: EDSMLayerDB) {
    const sector = await db.sectors.where('sector_number').equals(sector_number).first();
    console.log("Checking for EDSM updates for sector",sector);
    const updatedDate = sector.updatedDate;
    const [sx,sy,sz] = sector.sector_number;
    const jsonFilename = `edsm/${sx}/${sy}/${sx}_${sy}_${sz}.json.gz`;
    let res = await fetch(jsonFilename,{
      cache: 'no-cache',method: 'HEAD',});
    const lastModified = new Date(res.headers.get('Last-Modified'));
    console.log('updatedDate',updatedDate,'lastModified',lastModified);
    if (!updatedDate || new Date(updatedDate) < lastModified) {
      res = await fetch(jsonFilename,{
        cache: 'no-cache',method: 'GET',});
      console.log('importing data');
      const json = JSON.parse(ungzip(new Uint8Array(await res.arrayBuffer()),{to: 'string'}));
      console.log('extracted json',json);
      await db.transaction('rw',db.sectors,db.systems,async () => {
        console.log('started transaction');
        await db.systems.where('sector').equals(sector.sector_number).delete();
        console.log('deleted old data');
        for (const system of json) {
          const {coords,...rest} = system;
          const val = {...rest,...coords};
          await db.systems.add(val);
        };
        console.log('Added systems');
        sector.updatedDate = new Date();
        await db.sectors.put(sector);
      });

      console.log('Finished adding system data');
    } else {
      console.log('Systems for sector',sector,'already up-to-date.');
    }

  }

解决方法

看看您的代码片段,它似乎是一个节点程序? Dexie主要用于浏览器,但可以在带有IndexedDBShim的节点中执行。是这样吗然后,您必须避免使用async / await关键字,因为IndexedDBShim会过早触发其事务。

您可以通过将代码转换为ES5来解决此问题,或者可以避免使用async / await。

,

问题是我正在与异步运行代码

db.mytable.where(...).each((row) => { updateEDSMSector(row.sector_number,db) };

这将触发一个查询,但是对于每个查询结果,在updateEDSMSector内启动一个新事务。这些异步运行导致事务开始,而旧事务尚未正确关闭。我通过先获取db.mytable.where().toArray()然后对其进行循环来解决它。这仍然允许我的updateEDSMSector调用异步运行,但不会与已关闭的事务冲突。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。