前端与浏览器 / 进阶

IndexedDB 数据层:事务、索引与版本迁移

介绍对象仓库、索引、事务生命周期、版本升级和多标签页协调,构建可靠的本地数据层。 把它当数据库设计,而不是容量更大的 localStorage。

事务会自动失活

事务只在事件循环允许的活动窗口内保持可用。不要在事务中等待无关网络请求,再回来继续写入;先完成网络工作,再开启一个短事务提交结果。 同一事务中的多个写操作要共同成功或失败。把业务上必须一致的数据放进同一组 object store 的 readwrite 事务。

EXAMPLE / 01IndexedDB
const request = indexedDB.open('notes', 2);

request.onupgradeneeded = event => {
  const db = request.result;
  let store;
  if (!db.objectStoreNames.contains('documents')) {
    store = db.createObjectStore('documents', { keyPath: 'id' });
  } else {
    store = request.transaction.objectStore('documents');
  }
  if (!store.indexNames.contains('by-updated-at')) {
    store.createIndex('by-updated-at', 'updatedAt');
  }
};

升级要考虑其他标签页

旧页面保持数据库连接时,新版本可能触发 blocked。监听 versionchange,关闭旧连接并提示用户刷新。迁移逻辑应可从任意已发布版本逐步升级,不能只考虑上一版。 大规模数据变换不宜全部塞进 onupgradeneeded。可先升级结构,再在应用层分批迁移并记录进度。

最后回到真实页面检查

升级流程必须处理旧标签页和跨版本迁移