资讯详情

【sqllite3】Read error: SQLITE_BUSY: database is locked

📅 2026/10/10 5:15:47 | 华诺云谱 👁 阅读
【sqllite3】Read error: SQLITE_BUSY: database is locked
文章目录问题概述解决方案解决 SQLITE_BUSY 数据库锁定问题方案一使用数据库连接池或单例连接方案二使用 WAL 模式提高并发性能方案三添加重试机制处理临时锁定方案四确保事务正确关闭总结问题Uncaught Exception:This error originated either by throwing insideofanasyncfunctionwithout a catch block,or by rejecting a promise which was not handledwith.catch().The promise rejectedwiththe reasonRead error: SQLITE_BUSY: database is locked.概述这个错误包含两个相关问题SQLite 数据库锁定SQLITE_BUSY 和 未处理的 Promise 拒绝。以下是具体解决方案一、错误原因分析SQLITE_BUSY: database is lockedSQLite 数据库同一时间只允许一个写操作当多个进程 / 线程同时尝试读写时会导致数据库锁定。常见原因多个数据库连接同时操作同一文件事务未正确关闭导致长期锁定读写操作未加同步控制未处理的 Promise 拒绝数据库操作返回的 Promise 被拒绝如锁定错误但没有用 try/catch 或 .catch() 处理导致应用崩溃。解决方案处理未处理的 Promise 拒绝紧急修复首先确保所有数据库操作都有错误处理避免应用崩溃// 错误示例没有错误处理asyncfunctionreadData(){constresultawaitdb.get(SELECT * FROM table);// 若失败会导致未处理的拒绝}// 正确示例添加 try/catchasyncfunctionreadData(){try{constresultawaitdb.get(SELECT * FROM table);returnresult;}catch(err){console.error(数据库读取失败:,err);// 捕获并处理错误// 可选重试逻辑或 fallbackif(err.message.includes(SQLITE_BUSY)){console.log(数据库被锁定稍后重试...);awaitnewPromise(resolvesetTimeout(resolve,100));// 延迟后重试returnreadData();// 重试}}}对所有数据库操作get/all/run 等添加类似的错误处理。解决 SQLITE_BUSY 数据库锁定问题方案一使用数据库连接池或单例连接确保整个应用使用单一数据库连接避免多连接竞争// db.js - 单例模式管理数据库连接constsqlite3require(sqlite3).verbose();constdbPathpath/to/your/database.db;letdbInstancenull;functiongetDb(){if(!dbInstance){dbInstancenewsqlite3.Database(dbPath,(err){if(err){console.error(数据库连接失败:,err);}});}returndbInstance;}module.exportsgetDb;使用时始终通过getDb()获取连接确保全局唯一 javascriptconstgetDbrequire(./db);asyncfunctionqueryData(){constdbgetDb();// 执行操作...}方案二使用 WAL 模式提高并发性能SQLite 的 WALWrite-Ahead Logging模式允许同时进行读写操作减少锁定概率// 连接数据库时启用 WAL 模式constdbnewsqlite3.Database(dbPath,(err){if(err){console.error(连接失败:,err);return;}// 启用 WAL 模式db.run(PRAGMA journal_modeWAL;,(err){if(err){console.error(启用 WAL 模式失败:,err);}else{console.log(WAL 模式已启用);}});});方案三添加重试机制处理临时锁定当检测到 SQLITE_BUSY 时自动重试操作// 带重试的数据库操作工具函数asyncfunctionwithRetry(operation,maxRetries5,delay100){letretries0;while(retriesmaxRetries){try{returnawaitoperation();}catch(err){retries;if(err.message.includes(SQLITE_BUSY)retriesmaxRetries){console.log(数据库锁定第${retries}次重试...);awaitnewPromise(resolvesetTimeout(resolve,delay*retries));// 指数退避}else{throwerr;// 超过重试次数或其他错误抛出异常}}}}// 使用示例asyncfunctionreadConfig(){returnwithRetry(async(){constdbgetDb();returnnewPromise((resolve,reject){db.get(SELECT * FROM config,(err,row){if(err)reject(err);elseresolve(row);});});});}方案四确保事务正确关闭长时间未关闭的事务会导致数据库锁定确保事务完成后及时提交或回滚asyncfunctionupdateData(){constdbgetDb();try{awaitnewPromise((resolve,reject){db.run(BEGIN TRANSACTION,(err){if(err)returnreject(err);resolve();});});// 执行一系列操作awaitnewPromise((resolve,reject){db.run(UPDATE table SET ...,(err){if(err)returnreject(err);resolve();});});// 提交事务awaitnewPromise((resolve,reject){db.run(COMMIT,(err){if(err)returnreject(err);resolve();});});}catch(err){// 出错时回滚awaitnewPromise((resolve){db.run(ROLLBACK,resolve);});throwerr;}}总结优先处理未捕获的 Promise 拒绝给所有异步数据库操作添加 try/catch避免应用崩溃。解决数据库锁定启用 WAL 模式最简单有效使用单例连接添加重试机制确保事务及时关闭
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑