SQLite教程(十二):锁和并发控制详解
一、概述:
要深入理解SQLite数据库的稳定与可靠特性,其核心的锁与并发控制机制是必须掌握的关键。这套机制的具体实现,主要由pager_module模块负责。它如同一位严谨的守护者,严格保障着数据库事务的ACID(原子性、一致性、隔离性、持久性)特性,确保每一次数据操作要么完整提交,要么彻底回滚,不留中间状态。此外,该模块还高效地管理着内存缓存,将磁盘文件的数据页缓存在内存中,从而显著提升数据读写效率。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
值得注意的是,pager模块的设计是高度抽象的。它并不处理数据库文件的具体逻辑结构,例如B-Tree、编码格式或索引细节。在pager的视角中,整个数据库文件被简单地视为一系列大小固定(默认通常为1024字节,即1KB)的数据块的集合,每个块被称为一个“页”。页的编号从1开始,直观且连续,1号页即为文件的起始页。
二、文件锁机制详解:
为了实现多进程间的并发访问控制,SQLite设计了一套精密的文件锁状态机。在当前主流版本中,主要定义了五种锁状态,它们构成了协调读写操作的基础框架。
1). UNLOCKED(未锁定):
顾名思义,此状态表示数据库文件当前未被任何进程锁定。这是数据库的初始和空闲状态,任何进程都可以尝试对其进行读取或写入操作。
2). SHARED(共享锁):
当进程需要读取数据时,会获取共享锁。此状态下,数据库处于“只读模式”,允许多个进程同时持有共享锁进行读取,但禁止任何写入操作。只要存在一个有效的共享锁,写操作就必须等待。这是实现高并发读性能的核心。
3). RESERVED(保留锁):
这是一个“写意向锁”。当一个进程主要在读取数据,但已计划在稍后进行写入时,它会先获取一个保留锁。同一时间,一个数据库文件上只能存在一个保留锁,但它可以与多个共享锁共存。这种设计允许“读后写”的事务提前声明意图,避免了部分死锁情况。与Oracle等数据库的细粒度锁(行锁、表锁)相比,SQLite的文件级保留锁对并发性的影响更为显著。
4). PENDING(待定锁):
当持有保留锁的进程准备开始实际写入,但发现仍有其他进程持有共享锁时,它会将锁升级为PENDING状态。此时,写进程必须等待所有现有的读操作完成。关键之处在于,进入PENDING状态后,系统将拒绝新的读请求,以防止写操作被源源不断的读请求“饿死”。待所有现有共享锁释放后,PENDING锁才能进一步升级为排他锁。
5). EXCLUSIVE(排他锁):
这是进行数据写入所必需的终极锁状态。排他锁是独占的,一旦某个进程持有,其他任何类型的锁都无法再获取。因此,为了最大化数据库的并发能力,SQLite会极力优化,尽可能缩短持有排他锁的时间。
必须明确的是,SQLite将所有数据存储于单个文件,并仅提供文件级别的锁,这是一种粗粒度的锁策略。这与MySQL、PostgreSQL等支持行级锁、表级锁的“重量级”关系型数据库在架构上有本质区别。这直接影响了SQLite在高并发写入场景下的扩展性。这并非设计缺陷,而是一种针对嵌入式、轻量级应用场景的权衡。因此,选择合适的数据库时,必须清晰认识SQLite的适用边界。
三、回滚日志与崩溃恢复:
回滚日志是SQLite确保数据一致性与事务原子性的核心安全机制。当一个事务准备修改数据库时,其首要操作并非直接覆盖磁盘数据,而是将待修改页的原始内容完整备份到一个独立的回滚日志文件中。
对于涉及多个数据库文件的事务(ATTACH DATABASE),情况稍复杂:每个被修改的数据库都会生成自己的回滚日志(子日志),同时还会产生一个主日志文件用于全局协调。主日志记录了所有相关子日志的文件名,而每个子日志中也存储了主日志的信息。对于单数据库事务,该位置则为空。
这种日志常被称为“HOT”日志。它之所以“热”,是因为其唯一使命就是在系统崩溃或程序意外退出时,将数据库恢复到事务开始前的一致状态。在事务成功提交的正常流程中,该文件会被删除,仿佛从未存在过。
四、数据写入的完整流程:
下面,我们逐步拆解一个写事务的完整生命周期,看锁、日志与缓存如何协同工作。
准备阶段: 进程首先获取共享锁(SHARED),随即尝试获取保留锁(RESERVED)。保留锁是写入的“准入证”。若获取失败(通常因其他进程已持有),则立即返回SQLITE_BUSY错误。
日志记录: 成功获取保留锁后,进程创建回滚日志文件。在修改内存中的数据页缓存之前,会先将这些页的原始内容完整写入日志文件并同步到磁盘。此时,修改仅发生在内存,磁盘原文件未变,其他进程仍可正常读取。
写入与锁升级: 当缓存满或应用发起提交时,数据需写回磁盘。在此之前,写进程必须确保环境安全:
1. 强制将回滚日志中的所有数据刷入物理磁盘,这是崩溃恢复的保证。
2. 进行锁升级:先获取PENDING锁,再等待并获取排他锁(EXCLUSIVE)。此过程会等待所有现有共享锁释放,并阻止新读请求。
3. 将内存中已修改的“脏页”写回数据库磁盘文件。
若此次写盘仅因缓存满而非事务提交,则排他锁会持续持有。在后续修改新数据页前,需再次将更新的日志内容刷盘。这意味着从第一次刷盘到最终提交前,数据库将对其他所有进程锁定。
事务提交: 当最终提交事务时,流程如下:
4. 确认持有排他锁,且所有内存更改已写入磁盘文件。
5. 再次强制将数据库文件的更改刷入物理磁盘,确保持久化。
6. 关键步骤:删除回滚日志文件。 此操作是事务提交成功的最终标志。若删除前崩溃,下次启动时仍会利用该日志进行恢复。
7. 释放排他锁和PENDING锁。PENDING锁释放后,等待的读进程便可重新进入。
多数据库事务提交: 对于多数据库事务,提交逻辑更严谨:
4. 确保每个数据库均持有排他锁并拥有有效日志。
5. 创建主日志文件,记录所有子回滚日志的文件名。
6. 将主日志文件名回写到每个子日志的指定位置,建立双向关联。
7. 将所有数据库的更改持久化到磁盘。
8. 删除主日志文件(多数据库提交的关键标志)。
9. 删除各个数据库自身的回滚日志文件。
10. 释放所有数据库上的锁。
解决“写饥饿”: SQLite 3.x 版本针对“写饥饿”问题做了重要改进。在SQLite 2.x中,若数据库持续有读操作(共享锁不断),写操作可能永远无法获得锁。SQLite 3引入的PENDING锁机制解决了此问题:当有进程持有PENDING锁时,已存在的读操作可继续完成,但新的读请求会被阻塞。这确保了写操作在现有读操作结束后能获得执行机会。
五、SQL层的事务控制:
SQLite 3将底层锁机制与SQL语言层面的事务语义进行了优雅集成。默认情况下,每条SQL语句都在自动提交模式下运行,执行后立即提交。
当使用BEGIN TRANSACTION显式开启事务后,行为发生变化:BEGIN语句本身并不立即加锁。锁的获取与实际操作绑定——执行第一个SELECT时获取共享锁;执行第一个INSERT/UPDATE/DELETE时获取保留锁;而排他锁仅在提交阶段,数据从内存写入磁盘的短暂瞬间被持有。
一个需要注意的细节是:在同一数据库连接上,如果存在未完成的操作(如一个正在逐行输出结果的SELECT),自动提交会被延迟。即使另一个线程通过该连接执行了写操作,其提交也必须等待之前的读操作完全结束。
至此,关于SQLite核心并发与事务机制的探讨告一段落。本系列的后续内容将聚焦实战,提供具体的编程指南与典型应用示例,帮助您更好地运用SQLite。我们下篇再见。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
为xampp 安装pear db (database) 模块
在PHP开发环境中,通过PEAR包管理器更新并安装DB扩展是提升数据库操作效率的关键步骤。具体而言,我们需要首先同步pear php net的官方渠道源,随后执行DB软件包的安装指令。 详细操作命令如下:第一步,更新PEAR官方渠道:pear channel-update pear php net。
SQL Server 2005 Management Studio Express企业管理器将英文变成简体中文版的实现方法
SQL Server Management Studio安装后界面变英文?快速恢复中文版方法详解 许多用户在安装SQL Server Management Studio(SSMS)中文版后,发现软件界面意外显示为英文,这通常与安装路径的选择密切相关——尤其是当您未将软件安装在默认的C盘时。不必担心,
SQL Server把单个用户转换成多个用户的方法
SQL Server数据库“单个用户”状态锁定:快速诊断与彻底解决指南 近期,有技术团队在SQL Server 2008环境中还原备份数据库时,遇到了一个典型问题:目标数据库名称旁持续显示“单个用户”状态,并伴随连接访问错误。经排查,同一实例下的其他数据库运行完全正常,仅有该特定数据库出现此异常状况
sqlite时间戳转时间语句(时间转时间戳)
SQLite 时间日期转换实战代码详解 想要快速掌握 SQLite 中的时间格式转换吗?通过以下实例代码,您可以直观地学习如何将 UNIX 时间戳转换为本地时间,以及如何获取当前时间戳和格式化日期。这些操作在日常数据库管理中非常实用。 sqlite> SELECT datetime(13771688
SQLite数据库安装及基本操作指南
1 介绍 在嵌入式数据库领域,SQLite 是一个无法被忽视的经典选择。作为一款开源、轻量级、无需独立服务器的关系型数据库引擎,它以其自包含、零配置和完整的 SQL 事务支持而著称。SQLite 的核心优势在于其卓越的可移植性、极简的部署方式、紧凑的代码结构以及经过验证的高效性与可靠性。与其他数据
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

