indexeddb版本升级需显式控制:版本号严格递增且为正整数,结构变更仅限onupgradeneeded中执行,数据迁移须解耦并分片处理,多标签页需监听versionchange并提示刷新。

IndexedDB 的版本升级不是自动发生的,必须靠开发者显式控制版本号、编写迁移逻辑,并处理多标签页等现实约束。核心在于:版本号严格递增、结构变更只在 onupgradeneeded 中执行、数据迁移要与结构升级解耦。
版本号必须递增且为正整数
每次新增对象仓库、修改 keyPath、加删索引,都得提升版本号(如从 1 → 2 → 3),不能复用旧值,也不能用小数或字符串。传入低于当前版本的数字会直接抛 VersionError;传入非正整数(如 0、-1、“2”)也会失败。首次建库用 v1,后续每次结构变更都 +1。
- 浏览器只在
indexedDB.open(dbName, newVersion)的newVersion高于当前版本时才触发onupgradeneeded - 版本不变,哪怕代码里写了
createIndex,也不会生效——索引根本不会被创建 - 没有回滚机制;降级只能靠业务层提前备份 + 手动重建,不推荐
结构变更必须放在 onupgradeneeded 里
建表、删表、建索引、删索引,全部操作只能在这个回调中进行。它不是普通事件,而是唯一被授予 schema 操作权限的上下文。任何结构操作写在 onsuccess 或其他地方,都会报 InvalidStateError。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新增字段?不能原地改 objectStore,需先
deleteObjectStore,再用新定义重建 - 加索引前先检查:
store.indexNames.contains("email_idx"),避免重复建导致ConstraintError - 删字段?IndexedDB 不支持就地删除,要在重建 store 时省略该字段,并在后续数据迁移中清理旧值
- 每个操作都要幂等:建 store 前查
db.objectStoreNames.contains,删索引前确认存在
跨版本升级要覆盖所有中间路径
用户可能从 v1 直接打开 v3,中间 v2 的逻辑不能跳过。不能用 oldVersion === 1 判断,而要用小于比较,确保跃迁路径全覆盖。
if (event.oldVersionif (event.oldVersion- 推荐用 if/else if 链或 switch,按顺序检查每个版本门槛
- 每段逻辑都需独立判断、独立执行,且保持幂等
多标签页与大数据迁移要主动应对
另一个标签页连着旧版本数据库,会静默阻塞新页面的升级——onupgradeneeded 根本不触发,也无报错。同时,几万条记录的遍历绝不能塞进 onupgradeneeded,否则主线程卡死,旧版 Safari 超 50ms 就静默中止事务。
- 在
onsuccess拿到 db 实例后,立刻监听versionchange:db.addEventListener('versionchange', () => db.close()) - 配合 UI 提示:“检测到新版本,请刷新页面”
- 结构升级完成后,在普通 readwrite 事务中启动渐进式迁移
- 用独立元数据 store(如
meta)存标记(如{ migration_v2_done: true }),避免重复执行 - 每次处理 50–100 条,用
setTimeout或requestIdleCallback分片,游标 continue 前校验transaction.active === true
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










