You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IndexedDB无法创建object store 原有正常运行代码突然失效求助

IndexedDB对象仓库创建及数据操作异常修复

核心问题点

  • 版本升级被阻塞:页面初始化调用createIndexDb打开的数据库连接未关闭,后续调用createObjectStore触发版本升级时,浏览器会等待所有旧连接关闭才会执行onupgradeneeded回调,导致对象仓库创建流程卡住。
  • 错误被静默吞掉:原代码在升级逻辑外包裹了空catch块,所有操作报错都会被忽略,无法定位具体问题。
  • 手动提交升级事务无效:IndexedDB的版本升级事务是自动提交的,手动调用commit()属于多余操作,部分浏览器下反而会触发异常。
  • 全局连接状态失效:存储的全局database变量不会跟随版本升级自动更新,后续执行删除等操作时使用旧连接自然无法操作新的对象仓库。

修复后代码

JavaScript 代码

var dbName = "bmiDb1";
var lookupType = [];
var storeData = [{
  LookupTypeId: 2,
  Name: 'Collision',
  Description: null
}, {
  LookupTypeId: 3,
  Name: 'Grounding',
  Description: null
}]

// 通用打开数据库方法,支持指定版本和升级回调
function openDatabase(name, version = undefined, upgradeCallback = null) {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(name, version);
    request.onupgradeneeded = (event) => {
      if(upgradeCallback) upgradeCallback(event.target.result, event);
    };
    request.onsuccess = (event) => resolve(event.target.result);
    request.onerror = (event) => reject(event.target.error);
    request.onblocked = () => reject(new Error("数据库升级被旧连接阻塞,请关闭所有当前页面标签页后重试"));
  });
}

async function createObjectStore(storeName, keyName) {
  // 先获取当前最新版本
  const tempDb = await openDatabase(dbName);
  const currentVersion = tempDb.version;
  tempDb.close(); // 关闭临时连接避免阻塞升级
  
  // 升级版本创建对象仓库
  const newDb = await openDatabase(dbName, currentVersion + 1, (db) => {
    if (!db.objectStoreNames.contains(storeName)) {
      const objectStore = db.createObjectStore(storeName, { keyPath: keyName });
      // 升级事务内可以直接写入数据,不需要额外开事务
      storeData.forEach(data => objectStore.add(data));
    }
  });
  newDb.close();
}

// 示例删除数据方法
async function deleteStoreData(storeName, key) {
  const db = await openDatabase(dbName);
  const transaction = db.transaction(storeName, "readwrite");
  const store = transaction.objectStore(storeName);
  store.delete(key);
  transaction.oncomplete = () => db.close();
  transaction.onerror = (err) => {
    db.close();
    throw err;
  };
}

$(document).ready(async function() {
  // 初始化不需要存全局连接,每次操作打开连接用完就关即可,避免状态异常
  console.log("数据库初始化完成");
});

HTML 代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

额外优化建议

  • 每次数据库操作都临时打开连接,操作完成后主动关闭,避免连接长期占用导致升级阻塞
  • 不要吞掉任何错误,添加onblocked事件监听处理升级阻塞场景
  • 不需要维护全局版本号,每次升级前查询当前最新版本即可

内容的提问来源于stack exchange,提问作者Developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:24:01