当前位置: 首页 > news >正文

【sqllite3】Read error: SQLITE_BUSY: database is locked

文章目录

  • 问题
  • 概述
    • 解决方案
    • 解决 SQLITE_BUSY 数据库锁定问题
    • 方案一:使用数据库连接池或单例连接
    • 方案二:使用 WAL 模式(提高并发性能)
    • 方案三:添加重试机制(处理临时锁定)
    • 方案四:确保事务正确关闭
  • 总结

问题

Uncaught Exception: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Read error: SQLITE_BUSY: database is locked". 

概述

这个错误包含两个相关问题:SQLite 数据库锁定(SQLITE_BUSY) 和 未处理的 Promise 拒绝。以下是具体解决方案:
一、错误原因分析
SQLITE_BUSY: database is locked
SQLite 数据库同一时间只允许一个写操作,当多个进程 / 线程同时尝试读写时,会导致数据库锁定。常见原因:
多个数据库连接同时操作同一文件
事务未正确关闭,导致长期锁定
读写操作未加同步控制
未处理的 Promise 拒绝
数据库操作返回的 Promise 被拒绝(如锁定错误),但没有用 try/catch 或 .catch() 处理,导致应用崩溃。

解决方案

  1. 处理未处理的 Promise 拒绝(紧急修复)
    首先确保所有数据库操作都有错误处理,避免应用崩溃:
// 错误示例:没有错误处理
async function readData() {const result = await db.get('SELECT * FROM table'); // 若失败会导致未处理的拒绝
}// 正确示例:添加 try/catch
async function readData() {try {const result = await db.get('SELECT * FROM table');return result;} catch (err) {console.error('数据库读取失败:', err); // 捕获并处理错误// 可选:重试逻辑或 fallbackif (err.message.includes('SQLITE_BUSY')) {console.log('数据库被锁定,稍后重试...');await new Promise(resolve => setTimeout(resolve, 100)); // 延迟后重试return readData(); // 重试}}
}

对所有数据库操作(get/all/run 等)添加类似的错误处理。

解决 SQLITE_BUSY 数据库锁定问题

方案一:使用数据库连接池或单例连接

确保整个应用使用单一数据库连接,避免多连接竞争:

// db.js - 单例模式管理数据库连接
const sqlite3 = require('sqlite3').verbose();
const dbPath = 'path/to/your/database.db';let dbInstance = null;function getDb() {if (!dbInstance) {dbInstance = new sqlite3.Database(dbPath, (err) => {if (err) {console.error('数据库连接失败:', err);}});}return dbInstance;
}module.exports = getDb;使用时始终通过 getDb() 获取连接,确保全局唯一:javascript
const getDb = require('./db');async function queryData() {const db = getDb();// 执行操作...
}

方案二:使用 WAL 模式(提高并发性能)

SQLite 的 WAL(Write-Ahead Logging)模式允许同时进行读写操作,减少锁定概率:

// 连接数据库时启用 WAL 模式
const db = new sqlite3.Database(dbPath, (err) => {if (err) {console.error('连接失败:', err);return;}// 启用 WAL 模式db.run('PRAGMA journal_mode=WAL;', (err) => {if (err) {console.error('启用 WAL 模式失败:', err);} else {console.log('WAL 模式已启用');}});
});

方案三:添加重试机制(处理临时锁定)

当检测到 SQLITE_BUSY 时,自动重试操作:

// 带重试的数据库操作工具函数
async function withRetry(operation, maxRetries = 5, delay = 100) {let retries = 0;while (retries < maxRetries) {try {return await operation();} catch (err) {retries++;if (err.message.includes('SQLITE_BUSY') && retries < maxRetries) {console.log(`数据库锁定,第 ${retries} 次重试...`);await new Promise(resolve => setTimeout(resolve, delay * retries)); // 指数退避} else {throw err; // 超过重试次数或其他错误,抛出异常}}}
}// 使用示例
async function readConfig() {return withRetry(async () => {const db = getDb();return new Promise((resolve, reject) => {db.get('SELECT * FROM config', (err, row) => {if (err) reject(err);else resolve(row);});});});
}

方案四:确保事务正确关闭

长时间未关闭的事务会导致数据库锁定,确保事务完成后及时提交或回滚:

async function updateData() {const db = getDb();try {await new Promise((resolve, reject) => {db.run('BEGIN TRANSACTION', (err) => {if (err) return reject(err);resolve();});});// 执行一系列操作await new Promise((resolve, reject) => {db.run('UPDATE table SET ...', (err) => {if (err) return reject(err);resolve();});});// 提交事务await new Promise((resolve, reject) => {db.run('COMMIT', (err) => {if (err) return reject(err);resolve();});});} catch (err) {// 出错时回滚await new Promise((resolve) => {db.run('ROLLBACK', resolve);});throw err;}
}

总结

优先处理未捕获的 Promise 拒绝:给所有异步数据库操作添加 try/catch,避免应用崩溃。
解决数据库锁定:

  • 启用 WAL 模式(最简单有效)
  • 使用单例连接
  • 添加重试机制
  • 确保事务及时关闭
http://www.dtcms.com/a/415168.html

相关文章:

  • 做网站建设需要做哪些工作室什么平台可以打广告做宣传
  • Python爬虫实战:获取金价查询网最新金价行情与数据分析
  • 长春网站建设seo推广方式方法
  • 【MySQL✨】MySQL 入门之旅 · 第八篇:数据排序与分组
  • deepseek Kotlin Flow 全面详解
  • MTK-Android13-Dialer 通话界面定制修改
  • 化妆品电子商务网站开发流程描述中山网站建设推荐
  • 宿州移动网站建设广州模板网站
  • 旅游景区网站建设哈尔滨发布信息的网站
  • RVC WebUI(Retrieval-based-Voice-Conversion-WebUI)配置
  • 在线制作简历网站网页结构布局
  • 建网站要备案东莞网站制作品牌祥奔科技
  • 棋盘覆盖问题
  • 大邑网站建设百合居装饰公司官网
  • C++基础(3)-类的6个默认成员函数
  • 做营销型网站需要注意哪些点开发小程序费用
  • AI“点亮”萤火虫:边缘机器学习让微光成像走进4K时代
  • 【手撕机器学习 02】手撕算法的基石:精通NumPy与Pandas向量化思维
  • 一种好用开发的轻量级 Markdown 编辑器
  • 网站用户管理系统徐州市城乡建设局网站
  • 花店网站首页模版帝国cms使用教程
  • React-router v6学生管理系统笔记
  • 手写签名太麻烦?智能签名生成器免费实测 智能签名生成器、智能签名生成器使用、免费电子签名工具、Windows 电子签名软件、办公效率工具
  • 建设银行六安市分行网站hreflang wordpress
  • N8N Workflow Collection - 专业级自动化工作流库
  • 有没有专业做特产的网站小企业如何建网站
  • Android 6.0+ 动态权限请求模块,这个模块会包含 权限检查、请求、结果处理 等核心功能,并且支持 单个 / 多个权限请求、权限拒绝后的引导
  • Android -自定义Binding Adapter实战应用
  • 网站优化提升速度网站建设权利义务
  • 【复现】一种基于价格弹性矩阵的居民峰谷分时电价激励策略【需求响应】