使用Dexie在IndexedDB存大JSON遇AbortError事务中止问题求解
修复Dexie存储大数组时的AbortError问题
错误原因分析
你的代码核心问题是误用了Dexie的stores()方法:
stores()是用来定义数据库的表结构(schema),只能指定表名和索引规则,不能直接在这里插入数据。你把Itemslist的值设为JSON.stringify(this.AllItems),完全不符合语法,直接导致数据库初始化事务失败,抛出AbortError。- 另外80MB的大数组直接一次性插入也可能触发事务超时或内存压力,需要分批处理。
修复步骤及代码示例
正确定义数据库表结构
先在stores()里定义Itemslist表的结构,比如用自增ID作为主键,或者根据你的数据结构添加需要的索引。数据库打开后分批插入大数组
对于80MB的大数组,拆分成分块(比如每1000条为一批)插入,避免单次事务过大导致中止。
修正后的代码:
// 初始化数据库,注意去掉构造函数的多余逗号 var db = new Dexie("List"); // 定义表结构:list2表和Itemslist表的索引规则 db.version(2).stores({ list2: "++id,name", Itemslist: "++id" // 这里只定义表的主键/索引,不要放数据 }); // 打开数据库并插入数据 db.open() .then(async () => { const batchSize = 1000; // 每批插入的数量,可根据实际调整 const items = this.AllItems; const totalBatches = Math.ceil(items.length / batchSize); // 分批插入数据 for (let i = 0; i < totalBatches; i++) { const start = i * batchSize; const end = start + batchSize; const batch = items.slice(start, end); // 使用bulkAdd批量插入当前批次 await db.Itemslist.bulkAdd(batch); console.log(`完成第${i+1}/${totalBatches}批插入`); } console.log("所有数据插入完成"); }) .catch(e => { console.error("错误: ", e); });
额外注意事项
- 如果你的
AllItems里的对象有重复主键,bulkAdd会报错,可改用bulkPut(存在则更新,不存在则插入)。 - 若仍出现事务超时,可以进一步减小
batchSize,或者给事务设置更长的超时时间(Dexie默认事务超时可通过配置调整)。 - 确保
this.AllItems确实是一个合法的数组,没有循环引用等JSON序列化问题(不过Dexie会直接存储对象,不需要提前JSON.stringify)。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

