indexeddb升级需显式编排迁移逻辑:版本号严格递增、不可降级;越级升级须覆盖所有中间版本并保证幂等;多标签页需监听versionchange主动关闭旧连接;大数据迁移应分片执行而非阻塞主线程。

IndexedDB 本身不自动解决版本冲突,也不提供“一键迁移”能力。它的升级机制是事件驱动、严格递增、跨标签页敏感的——冲突不是异常,而是设计常态;迁移不是后台任务,而是开发者必须显式编排的逻辑流程。
版本号只能升不能降,降级会直接失败
调用 indexedDB.open(dbName, version) 时,若传入的 version 小于当前数据库版本,浏览器立即抛出 VersionError,数据库打不开。这意味着:
- 没有回滚机制,也无法还原旧结构或数据
- 所谓“回退”,只能靠业务层提前备份 + 手动重建旧库(极不推荐)
- 版本号必须是正整数(1、2、3…),不能用小数、字符串或 0
越级升级要手动分步处理中间变更
从 v1 直接指定 v3,IndexedDB 会依次触发 v2 和 v3 的 onupgradeneeded,但不会自动执行 v2 的迁移逻辑——你得自己判断并覆盖所有跃迁路径:
- 用
event.oldVersion 而不是 <code>=== 1,确保 v1→v3 时 v2 的逻辑也被执行 - 推荐用 if/else if 链或 switch,按顺序检查每个版本门槛
- 每段迁移代码必须幂等:建表前先
db.objectStoreNames.contains('store'),建索引前查store.indexNames.contains('idx')
多标签页会静默阻塞升级,必须主动监听 versionchange
只要另一个标签页还连着旧版本数据库,新页面的 onupgradeneeded 就不会触发,且通常无报错——这是最隐蔽的升级失败原因。
- 在
onsuccess回调拿到IDBDatabase实例后,立刻绑定db.addEventListener('versionchange', () => db.close()) - 可配合提示:“检测到新版本,请刷新页面”
- 不要等写操作失败才响应,这是预防性动作,不是补救措施
大数据迁移不能放在 onupgradeneeded 里
结构变更(建表、建索引)可以放进去,但遍历几万条记录改字段、补数据等耗时操作,绝不能写在这里:
- 会卡主线程,可能被浏览器中止事务
- 旧版 Safari 等对 upgrade 事务时长极其敏感,超 50ms 就静默 abort
- 应拆成小批次(如每次 100 条),用
requestIdleCallback或定时器分片执行 - 用独立元数据 store(如
meta)记录进度,避免重复迁移
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











