sqlite锁表

news/2024/10/8 7:30:34/文章来源:https://www.cnblogs.com/music-liang/p/18450896

 

 

在使用 SQLite 进行读写操作时,出现**锁表**(table lock)通常是由于数据库的并发访问导致的。SQLite 本质上是一个文件数据库,它的并发处理能力相对有限,默认情况下,SQLite 使用锁机制来确保数据的一致性和防止竞争条件的发生。当一个事务在进行写操作时,会为整个数据库加上锁,阻止其他事务进行写入或读取,直到写操作完成。

### 出现锁表的原因:
1. **多个事务并发写入**:SQLite 在写操作时会加一个排他锁(exclusive lock),这意味着在写操作完成之前,其他读写操作都无法进行。
2. **长时间的事务未提交**:如果一个事务在执行期间没有及时提交或回滚(例如,事务执行时间过长),其他事务会被阻塞。
3. **多个连接争用资源**:如果你的程序在短时间内频繁发起多个数据库连接进行读写操作,可能会导致锁冲突。
4. **读写混合操作**:SQLite 默认使用读锁和写锁机制,多个读操作可以同时进行,但一旦发生写操作,其他的读操作就可能被阻塞。

### 避免锁表的解决方案:
1. **尽量缩短事务的执行时间**:
- 将事务的处理时间最小化,快速提交或回滚。长时间的事务会导致其他操作被锁住。

2. **优化并发访问**:
- 使用合适的锁模式,确保在同一时间只有一个写操作。可以通过合理的读写调度来减少锁冲突。

3. **使用 WAL(Write-Ahead Logging)模式**:
- SQLite 的 WAL 模式允许读写并发进行,在这种模式下,读操作不会被写操作阻塞。你可以通过以下 SQL 语句开启 WAL 模式:
```sql
PRAGMA journal_mode=WAL;
```
- WAL 模式允许读操作和写操作更好地共存,因为写操作是在独立的 WAL 文件中完成的。

4. **处理好数据库连接**:
- 尽量减少数据库连接数,重用已有连接。频繁创建和销毁连接可能导致锁冲突。
- 可以使用连接池来优化数据库连接管理。

5. **合理使用事务**:
- 将读操作和写操作分开处理,避免在同一事务中进行大量的读写混合操作。

6. **检测锁并重试**:
- 如果一个事务因锁表失败,可以设计代码在失败时稍微延迟并重试。例如,使用 `sqlite3_busy_timeout()` 函数设置忙等待时间来处理锁争用问题:
```cpp
sqlite3_busy_timeout(db, 1000); // 设置忙等待时间为 1000 毫秒
```

### 代码示例:
假设你有一个写操作,可以通过如下方式来优化:

```cpp
#include <iostream>
#include <sqlite3.h>

int execute_query(sqlite3* db, const char* sql) {
char* errMsg = 0;
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
std::cerr << "SQL error: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
return rc;
}

int main() {
sqlite3* db;
int rc = sqlite3_open("example.db", &db);

// 设置 WAL 模式
execute_query(db, "PRAGMA journal_mode=WAL;");

// 设置忙等待时间
sqlite3_busy_timeout(db, 1000); // 等待 1000 毫秒

if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
return rc;
} else {
std::cout << "Opened database successfully" << std::endl;
}

// 开始一个事务
execute_query(db, "BEGIN TRANSACTION;");

// 执行插入操作
execute_query(db, "INSERT INTO test (name, age) VALUES ('John', 30);");

// 提交事务
execute_query(db, "COMMIT;");

sqlite3_close(db);
return 0;
}
```

这个代码中,我们开启了 WAL 模式并设置了忙等待时间来减少锁表的几率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809781.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)

致敬传奇调题王 HDK A.Meaning Mean给定一个序列 \(a\),每次选择 \(i,j\ (i\neq j)\),使得其缩成一个值为 \(\lfloor\frac{a_i+a_j}{2}\rfloor\) 的数,直至剩余一个数,求最终答案的最大值一开始想的是最小化 \(\lfloor\frac{a_i+a_j}{2}\rfloor\) 的损失,后来发现这点损失…

读数据工程之道:设计和构建健壮的数据系统02数据工程师

数据工程师1. 背景和技能 1.1. 数据工程是一个快速发展的领域,关于如何成为一名数据工程师仍然存在很多问题 1.2. 进入数据工程领域的人在教育、职业和技能方面有着不同的背景1.2.1. 每个进入该领域的人都应该投入大量的时间进行自学1.3. 从一个邻近的领域转到数据工程是最容易…

销售秘籍:故事+观点+结论

在销售的浩瀚宇宙中,隐藏着一个不朽的秘诀——利用人类共有的“错失恐惧”,激发客户内心的渴望与行动。正如村上春树所言,每个故事都深深植根于灵魂,而大仲马则揭示,灵魂之眼所见,比肉眼更为长久铭记。 错失恐惧:销售心理学的隐形推手 作为社会性生物,我们天生害怕错过…

面相快速入门教程5水性

5 水性 在本章中,我将介绍水元素的基本知识,并让你学会如何识别水元素。首先,我们来快速参考一下水元素的特征:能量:黑暗、静止、漂浮、安静、夜晚、冬天、死亡、出生前 特质:睿智、勇敢、恐惧、顽强、果断、任性、独立、坚强、忧郁、固执、神秘、反思、多梦、艺术、神秘…

修改PE入口点方式注入自己编写的DLL——《英雄无敌》1代小回城术修改成大回城术

《英雄无敌》每代都有回城术,而第一代的回城术则是所谓的“小回城术”,就是到达的城堡不能选择。到了《英雄无敌》2代和3代,都有大小回城术了,而大回城术可以使英雄回到己方的任意一座没有自己的英雄所在的城堡,有了这样的魔法,使得英雄能兼顾整个地图,是每个玩家都是首…

Architecture 1001: x86-64 Assembly 汇编

编程语言心法参考:http://www.yinwang.org/blog-cn/2017/07/06/master-pl 英语阅读速成:http://www.yinwang.org/blog-cn/2018/11/23/grammar 前置条件 必须熟悉 C 编程。 https://www.learn-c.org/ https://www.edx.org/certificates/professional-certificate/dartmouth-im…

《机器学习》 学习记录 - 第二章

好多看不懂的高数内容。。。 第2章 模型评估与选择 2.1 经验误差与过拟合错误率(error rate):分类错误的样本数占样本总数的比例。 若在m个样本中有a个样本分类错误,则错误率\(E=a/m\); 而常说的 精度 则等于\(1-a/m\),即 “精度=1-错误率” ,常写为百分比形式。训练误差(…

git push代码失败,鉴权失败

github 无法push 代码 1、确保设置了用户名和邮箱 git config --global user.name "mars" git config --global user.email "mars3603@163.com" 2、修改 .git/config 中的URL,将https的方式修改为 ssh https方式:url = https://github.com/Mars3603/grpc…

织物图像的配准和拼接算法的MATLAB仿真,对比SIFT,SURF以及KAZE

1.算法运行效果图预览 (完整程序运行后无水印)SIFT: surf:kaze: 2.算法运行软件版本 MATLAB2022a3.部分核心程序 (完整版代码包含注释和操作步骤视频)img1 = imread(Images\F1.jpg); img2 = imread(Images\F2.jpg); figure; subplot(121); imshow(img1); title(原始图片1)…

06.OpenFeign接口调用

1.提问 1.1 已经有RestTemplate + LoadBalancer的方式进行服务的调用,为什么还要有OpenFeign? 因为OpenFeign的功能更强大,和使用更便携。 1.2 使用那个? 推荐使用OpenFeign 2.OpenFeign是什么 2.1 官网翻译 https://docs.spring.io/spring-cloud-openfeign/reference/spri…

Hadoop单机模式

1.安装JDK 1.1 下载解压 tar zxf jdk-8u151-linux-x64.tar.gz -C /usr/local/src mv jdk-8u151-linux-x64 java1.2 添加环境变量 export JAVA_HOME=/usr/local/src/java export PATH=$PATH:$JAVA_HOME/binsource /etc/prifile java -version2.安装Hadoop 1.1 下载解压 tar zxf …

mysql读写分离的最佳实践

一. 传统的读写分离方式 在 MySQL 中实现读写分离可以通过以下几种方式来达到目的: 1. 主从复制 使用主从复制(Master-Slave Replication)是实现读写分离的常见方式。主库:处理所有的写入操作(INSERT、UPDATE、DELETE)。 从库:负责处理读操作(SELECT)。步骤:设置主从…