启动 Dexie 事务时出现 TransactionInactiveError
TransactionInactiveError when starting a Dexie transaction
我有一个服务函数(使用 typescript 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.');
}
}
看你的代码片段,好像是一个node程序? Dexie 主要用于浏览器,但可以使用 IndexedDBShim 在节点中执行。是这样吗?那么您必须避免使用 async / await 关键字,因为 IndexedDBShim 会过早触发其事务。
您可以通过将代码转译为 ES5 来解决这个问题,或者您可以避免使用 async/await.
问题是我运行宁代码与
异步
db.mytable.where(...).each((row) => { updateEDSMSector(row.sector_number, db) };
这会触发一个查询,但对于每个查询结果,都会在 updateEDSMSector 中启动一个新事务。这些 运行ning 异步导致事务开始,而旧事务尚未正确关闭。我通过首先获取 db.mytable.where().toArray()
然后遍历 those.This 来修复它仍然允许我的 updateEDSMSector
异步调用 运行,但不会与已关闭的事务发生冲突。
我有一个服务函数(使用 typescript 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.');
}
}
看你的代码片段,好像是一个node程序? Dexie 主要用于浏览器,但可以使用 IndexedDBShim 在节点中执行。是这样吗?那么您必须避免使用 async / await 关键字,因为 IndexedDBShim 会过早触发其事务。
您可以通过将代码转译为 ES5 来解决这个问题,或者您可以避免使用 async/await.
问题是我运行宁代码与
异步db.mytable.where(...).each((row) => { updateEDSMSector(row.sector_number, db) };
这会触发一个查询,但对于每个查询结果,都会在 updateEDSMSector 中启动一个新事务。这些 运行ning 异步导致事务开始,而旧事务尚未正确关闭。我通过首先获取 db.mytable.where().toArray()
然后遍历 those.This 来修复它仍然允许我的 updateEDSMSector
异步调用 运行,但不会与已关闭的事务发生冲突。