1***@163.com
1***@163.com
  • 发布:2026-06-23 09:14
  • 更新:2026-06-23 09:15
  • 阅读:69

sqlite 只要热更新就会失败 怎么解决

分类:uni-app

plus.sqlite.openDatabase 打开数据库 只要app热更新就会失败 包括app的wgt更新,这怎么解决啊,不能每次都需要手动重启一下app啊

2026-06-23 09:14 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

这个问题在 uni-app 开发中非常经典,本质上是 热更新(HBuilderX 基座调试时的热重载)导致数据库连接句柄失效,但应用没有重新打开数据库导致的。

根据知识库中的官方回复和社区经验,解决方案如下:

核心原因

在 iOS 或部分 Android 环境下,HBuilderX 触发代码热更新时,底层的原生引擎会重启或重置部分状态,之前通过 plus.sqlite.openDatabase 打开的数据库连接会被关闭或变为只读状态。此时如果代码逻辑中判断“数据库已打开”就直接执行写入操作,就会报 readonly database 错误。

解决方案:在操作前重新打开数据库

最稳妥的做法是,在每次执行增删改查之前,不要依赖之前打开的连接状态。你应该在操作前先调用 plus.sqlite.isOpenDatabase 判断,如果已打开则先关闭再重新打开,或者封装一个“获取可用数据库连接”的方法。

方案一:简单粗暴的重启连接(推荐用于调试阶段)

App.vueonLaunch 或页面初始化时,不再直接打开数据库,而是封装一个 getDB 函数:

// 数据库操作工具 js  
const dbName = 'myAppDB';  
const dbPath = '_doc/myAppDB.db';  

function openDB() {  
  return new Promise((resolve, reject) => {  
    // 1. 先尝试关闭可能残留的只读连接  
    plus.sqlite.closeDatabase({  
      name: dbName,  
      success: () => {  
        console.log('旧连接已关闭,准备重新打开');  
        realOpen(resolve, reject);  
      },  
      fail: () => {  
        // 关闭失败通常意味着本来就没打开,直接尝试打开即可  
        realOpen(resolve, reject);  
      }  
    });  
  });  
}  

function realOpen(resolve, reject) {  
  plus.sqlite.openDatabase({  
    name: dbName,  
    path: dbPath,  
    success: (e) => {  
      console.log('数据库重新打开成功');  
      resolve(e);  
    },  
    fail: (e) => {  
      console.error('数据库打开失败', e);  
      reject(e);  
    }  
  });  
}  

// 在需要操作数据库的地方调用  
async function insertData() {  
  await openDB(); // 确保每次操作前都是全新的连接  
  // 执行 insert 或 update...  
}

本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

方案二:iOS 设备在热重启前主动关闭(针对线上 wgt 热更新)

如果你指的是 wgt 包的线上热更新(调用 plus.runtime.installplus.runtime.restart() 重启应用),在 iOS 上重启后也容易出现只读问题。根据知识库中的社区反馈,可以在调用 restart() 之前,主动关闭数据库

plus.runtime.install(downloadResult.tempFilePath, {  
  force: false  
}, function() {  
  // 安装成功,准备重启  
  try {  
    plus.sqlite.closeDatabase({ name: 'myAppDB' });  
  } catch (e) {  
    console.log('关闭数据库忽略报错');  
  }  
  plus.runtime.restart();  
});

本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

重启后,应用重新走 onLaunch 流程,正常打开数据库即可。

特别注意

  • 鸿蒙平台 (HarmonyOS):根据知识库记录,鸿蒙平台目前对 plus.sqlite 和热更新(wgt)的支持尚不完善,有开发者反馈 plus.runtime.install 执行后重启未生效或第二次更新报错。如果是鸿蒙平台遇到此问题,暂时没有完美的官方修复方案,建议关注官方后续更新或尝试整包更新。
  • 不要使用 isOpenDatabase 作为免开库的依据:很多开发者喜欢先判断 isOpenDatabase,如果为 true 就不重新打开。但在热更新场景下,这个连接虽然显示“打开”,实际上已经是只读状态了,必须关闭重开。

如果上述方案仍然无法解决,可以参考社区一个临时处理方案:在 iOS 设备 restart 之前务必关闭数据库,让重启流程自然触发重新打开。更多讨论见 ask 社区相关帖子

内容为 AI 生成,仅供参考

要回复问题请先登录注册