切换WatermelonDB至SQLiteAdapter时EBUSY错误求助
解决WatermelonDB SQLiteAdapter的EBUSY资源锁定错误
问题分析
错误EBUSY: resource busy or locked, unlink 'C:\Myapp\myDB.db'出现在WatermelonDB尝试重置数据库时,核心原因是SQLite数据库文件(或其关联的myDB.db-wal/myDB.db-shm临时文件)被未关闭的连接、外部进程占用,导致无法完成删除操作。
解决方案
1. 确保WatermelonDB实例唯一且正确销毁
- 检查代码中是否存在重复初始化SQLiteAdapter或Database实例的情况,比如热重载、测试场景中多次创建实例会导致旧连接未释放,持续锁定文件。
- 在重置数据库前,先调用
database.destroy()彻底销毁现有实例,再重新初始化:// 销毁现有数据库实例 await database.destroy(); // 重新初始化SQLiteAdapter与Database const adapter = new SQLiteAdapter({ dbName: 'myDB', // 增加SQLite超时配置,等待锁释放 sqliteOptions: { timeout: 5000 } }); const database = new Database({ adapter, modelClasses: [/* 你的数据模型 */], });
2. 关闭所有手动创建的SQLite连接
你提到用const db = new sqlite3.Database(dbPath, { open: false })检查连接,即使open设为false,也要确保调用db.close()释放资源:
const db = new sqlite3.Database(dbPath, { open: false }); // 检查完成后立即关闭连接 db.close((err) => { if (err) console.error('关闭SQLite连接失败:', err); });
3. 清理SQLite关联的临时文件
SQLite会自动生成*.db-wal(写前日志)和*.db-shm(共享内存)文件,这些文件也可能被锁定:
- 停止应用后,手动删除
C:\Myapp\目录下的myDB.db、myDB.db-wal、myDB.db-shm三个文件,再重新启动应用。
4. 排除外部进程占用
Windows环境下,以下场景可能锁定数据库文件:
- 文件资源管理器正在打开
C:\Myapp目录 - 杀毒软件、备份工具正在扫描该文件
- 其他正在运行的Node.js进程占用了数据库连接
关闭上述进程后,重新启动应用测试。
5. 调整SQLiteAdapter的配置参数
初始化SQLiteAdapter时,增加超时配置让SQLite等待锁释放,极端情况下可临时调整日志模式:
const adapter = new SQLiteAdapter({ dbName: 'myDB', sqliteOptions: { // 设置超时时间(毫秒),等待锁释放 timeout: 10000, // 极端场景下尝试禁用WAL模式(不推荐长期使用) // journalMode: 'DELETE' } });
6. 替换同步删除为异步操作
错误栈显示调用了unlinkSync同步删除文件,Node.js中同步IO容易引发锁冲突,测试场景下可改为异步删除:
const fs = require('fs').promises; // 重置数据库前异步删除旧文件 try { await fs.unlink('C:\Myapp\myDB.db'); } catch (err) { // 文件不存在时忽略错误 if (err.code !== 'ENOENT') throw err; }
内容的提问来源于stack exchange,提问作者tatqna
相关产品推荐
相关产品推荐

