- 浏览: 29844 次
- 性别:
- 来自: 广州
-
最新评论
写在前面:本节
讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一 Jim
Gray(曾任职微软)就是因为在事务处理方面的成就而获得这一殊荣,正是因为他,才使得OLTP系统在随后直到今天大行其道.关于事务处理技术,涉及到
很多,随便就能写一本书.在这里我只讨论SQLite事务实现的一些原理,SQLite的事务实现与大型通用的DBMS相比,其实现比较简单.这些内容可
能比较偏于理论,但却不难,也是理解其它内容的基础.好了,下面开始第二节---事务.
2、 事务(Transaction)
2.1、事务的周期(Transaction Lifecycles)
程
序与事务之间有两件事值得注意:
(1) 哪些对象在事务下运行——这直接与API有关。
(2)
事务的生命周期,即什么时候开始,什么时候结束以及它在什么时候开始影响别的连接(这点对于并发性很重要)——这涉及到SQLite的具体实现。
一
个连接(connection)可以包含多个(statement),而且每个连接有一个与数据库关联的B-tree和一个pager。Pager在连接
中起着很重要的作用,因为它管理事务、锁、内存缓存以及负责崩溃恢复(crash
recovery)。当你进行数据库写操作时,记住最重要的一件事:在任何时候,只在一个事务下执行一个连接。这些回答了第一个问题。
一般来说,
一个事务的生命和statement差不多,你也可以手动结束它。默认情况下,事务自动提交,当然你也可以通过BEGIN..COMMIT手动提交。接下
来就是锁的问题。
2.2、锁的状态(Lock States)
锁
对于实现并发访问很重要,而对于大型通用的DBMS,锁的实现也十分复杂,而SQLite相对较简单。通常情况下,它的持续时间和事务一致。一个事务开
始,它会先加锁,事务结束,释放锁。但是系统在事务没有结束的情况下崩溃,那么下一个访问数据库的连接会处理这种情况。
在SQLite中有5种不
同状态的锁,连接(connection)任何时候都处于其中的一个状态。下图显示了相应的状态以及锁的生命周期。
关于这个图有以下几点值得注意:
(1)
一个事务可以在UNLOCKED,RESERVED或EXCLUSIVE三种状态下开始。默认情况下在UNLOCKED时开始。
(2)
白色框中的UNLOCKED, PENDING, SHARED和 RESERVED可以在一个数据库的同一时存在。
(3)
从灰色的PENDING开始,事情就变得严格起来,意味着事务想得到排斥锁(EXCLUSIVE)(注意与白色框中的区别)。
虽然锁有这么多状
态,但是从体质上来说,只有两种情况:读事务和写事务。
2.3、读事务(Read
Transactions)
我们先来看看SELECT语句执行时锁的状态变化过程,非常简单:一个连接执行select语句,触
发一个事务,从UNLOCKED到SHARED,当事务COMMIT时,又回到UNLOCKED,就这么简单。
考虑下面的例子(为了简单,这里用
了伪码):
db = open('foods.db') db.exec('BEGIN') db.exec('SELECT * FROM episodes') db.exec('SELECT * FROM episodes') db.exec('COMMIT') db.close()
由
于显式的使用了BEGIN和COMMIT,两个SELECT命令在一个事务下执行。第一个exec()执行时,connection处于SHARED,然
后第二个exec()执行,当事务提交时,connection又从SHARED回到UNLOCKED状态,如下:
UNLOCKED→PENDING→SHARED→UNLOCKED
如
果没有BEGIN和COMMIT两行时如下:
UNLOCKED→PENDING→SHARED→UNLOCKED→PENDING→
SHARED→UNLOCKED
2.4、写事务(Write
Transactions)
下面我们来考虑写数据库,比如UPDATE。和读事务一样,它也会经历
UNLOCKED→PENDING→SHARED,但接下来却是灰色的PENDING,
2.4.1、The Reserved States
当一个连接(connection)向数据库写数据时,从
SHARED状态变为RESERVED状态,如果它得到RESERVED锁,也就意味着它已经准备好进行写操作了。即使它没有把修改写入数据库,也可以把
修改保存到位于pager中缓存中(page cache)。
当一个连接进入RESERVED状态,pager就开始初始化恢复日志
(rollback journal)。在RESERVED状态下,pager管理着三种页面:
(1) Modified
pages:包含被B-树修改的记录,位于page cache中。
(2) Unmodified
pages:包含没有被B-tree修改的记录。
(3) Journal pages:这是修改页面以前的版本,这些并不存储在page
cache中,而是在B-tree修改页面之前写入日志。
Page
cache非常重要,正是因为它的存在,一个处于RESERVED状态的连接可以真正的开始工作,而不会干扰其它的(读)连接。所以,SQLite可以高
效的处理在同一时刻的多个读连接和一个写连接。
2.4.2 、The
Pending States
当一个连接完成修改,就真正开始提交事务,执行该过程的pager进入EXCLUSIVE状态。从
RESERVED状态,pager试着获取 PENDING锁,一旦得到,就独占它,不允许任何其它连接获得PENDING锁(PENDING is a
gateway
lock)。既然写操作持有PENDING锁,其它任何连接都不能从UNLOCKED状态进入SHARED状态,即没有任何连接可以进入数据(no
new readers, no new
writers)。只有那些已经处于SHARED状态的连接可以继续工作。而处于PENDING状态的Writer会一直等到所有这些连接释放它们的锁,
然后对数据库加EXCUSIVE锁,进入EXCLUSIVE状态,独占数据库(讨论到这里,对SQLite的加锁机制应该比较清晰了)。
2.4.3、The Exclusive State
在EXCLUSIVE状态下,主
要的工作是把修改的页面从page cache写入数据库文件,这是真正进行写操作的地方。
在pager写入modified
pages之前,它还得先做一件事:写日志。它检查是否所有的日志都写入了磁盘,而这些通常位于操作的缓冲区中,所以pager得告诉OS把所有的文件写
入磁盘,这是由程序synchronous(通过调用OS的相应的API实现)完成的。
日志是数据库进行恢复的惟一方法,所以日志对于DBMS非
常重要。如果日志页面没有完全写入磁盘而发生崩溃,数据库就不能恢复到它原来的状态,此时数据库就处于不一致状态。日志写入完成后,pager就把所有的
modified pages写入数据库文件。接下来就取决于事务提交的模式,如果是自动提交,那么pager清理日志,page
cache,然后由EXCLUSIVE进入UNLOCKED。如果是手动提交,那么pager继续持有EXCLUSIVE锁和保存日志,直到COMMIT
或者ROLLBACK。
总之,从性能方面来说,进程占有排斥锁的时间应该尽可能的短,所以DBMS通常都是在真正写文件时才会占有排斥
锁,这样能大大提高并发性能。
发表评论
-
(转)Andriod是什么
2010-12-02 11:24 1617导读:Sans Serif是Google的 ... -
(转)SQLite入门与分析(六)---再谈SQLite的锁
2010-11-19 00:09 944写在前 面:SQLite封锁机制的实现需要底层文件系统的 ... -
(转)SQLite入门与分析(五)---Page Cache之并发控制
2010-11-19 00:05 1059写在前面:本节主要谈 ... -
(转)SQLite入门与分析(四)---Page Cache之事务处理(3)
2010-11-19 00:01 969Code 写在前面:由于 内容较多,所以断续没有写完的 ... -
(转)SQLite入门与分析(四)---Page Cache之事务处理(2)
2010-11-18 23:57 1160写在前面:个人认为pager层是SQLite实现最为核心的 ... -
(转)SQLite入门与分析(四)---Page Cache之事务处理(1)
2010-11-18 23:53 951写在前面:从本章开始,将对SQLite的每个模块进行讨论。 ... -
(转)SQLite入门与分析(三)---内核概述(2)
2010-11-18 23:48 1312写在前面:本节 是前 ... -
(转)SQLite入门与分析(三)---内核概述(1)
2010-11-18 23:41 802写在前面:从本 章开始, ... -
(转)SQLite入门与分析(二)---设计与概念
2010-11-18 23:35 802写在前面:谢谢各位的 ... -
(转)SQLite入门与分析(一)
2010-11-18 23:31 918写在前面:出于项目的 需要,最近打算对SQLite的内核 ... -
(转)深入研究B树索引(五)续
2010-11-18 15:10 9305.3 重建 B 树索引 ... -
(转)深入研究B树索引(五)
2010-11-18 15:07 11975. 重建 B ... -
(转)深入研究B树索引(四)续
2010-11-18 14:58 9274.2 B 树索引的对于删除( DEL ... -
(转)深入研究B树索引(三、四)
2010-11-18 14:44 7293. B 树索 ... -
(转)深入研究B树索引(二)
2010-11-18 14:20 7642. B 树索引的内部结构 ... -
(转)深入研究B树索引(一)
2010-11-18 14:12 1009摘要: 本文对B 树索引的结构、内部管理等方面做了一个全面 ... -
(转)B树、B-树、B+树、B*树都是什么
2010-11-17 23:46 678B 树 即二叉搜 ... -
画UML图时注意的几个原则(转)
2010-08-03 12:34 1641软件开发中,分析和设计时,文档的编写和思想的交流,经常要绘制各 ... -
你是个软件架构师吗?(转)
2010-07-14 11:11 670开发和架构的界限难以 ... -
(转)同曲异奏——高效能项目团队的五大特点
2010-03-29 00:24 866同曲异奏——高效能项 ...
相关推荐
"sqlite-tools-win-x64-3440200.zip"这个压缩包包含了三个主要的SQLite实用工具,它们分别是sqlite3_analyzer.exe、sqlite3.exe和sqldiff.exe。 1. **sqlite3.exe**:这是SQLite的命令行接口,也是最基础的工具。...
在SQLite入门与分析(七)---浅谈SQLite的虚拟机.doc中,主要讲解了SQLite如何通过虚拟机执行SQL语句。SQLite的虚拟机,也称为VDBE(Virtual Database Engine),是SQLite的核心组件。它负责解析SQL语句,将其转化为一...
赠送jar包:sqlite-jdbc-3.15.1.jar; 赠送原API文档:sqlite-jdbc-3.15.1-javadoc.jar; 赠送源代码:sqlite-jdbc-3.15.1-sources.jar; 赠送Maven依赖信息文件:sqlite-jdbc-3.15.1.pom; 包含翻译后的API文档:...
sqlite-devel-3.7.17-8.el7.x86_64.rpm
在“sqlite-tools-linux-x86-3350400.zip”这个压缩包中,包含了以下关键的SQLite工具: 1. **sqlite3**: 这是SQLite的主要命令行接口。用户可以通过这个工具执行SQL语句,创建和管理数据库,查询数据,甚至进行...
SQLite3.exe 是 SQLite 数据库引擎的一个命令行接口工具,它允许用户通过文本命令与 SQLite 数据库进行交互。SQLite 是一个开源、轻量级、自包含的 SQL 数据库引擎,广泛应用于嵌入式系统和移动应用中,因为它无需...
SQLite-1.0.66.0-setup安装包
SQLiteStudio是一款功能强大的SQLite数据库管理工具,专为Windows操作系统设计。SQLite本身是一个开源、轻量级的嵌入式SQL数据库引擎,广泛应用于各种桌面应用程序、移动设备和服务器环境,尤其适合那些对数据库性能...
标题 "sqlite-netFx40-binary-x64-2010-1.0.106.0" 指的是一个针对 .NET Framework 4.0 平台的 SQLite 驱动程序的特定版本,适用于64位(x64)系统。这个版本号1.0.106.0表明这是一个更新稳定版。SQLite 是一个轻量...
编译器则包括分词器和分析器,将 SQL 查询转化为语法树,再由代码生成器转换为针对 SQLite 的汇编代码,最终由虚拟机执行。虚拟机,即虚拟数据库引擎 (VDBE),类似 Java 虚拟机,解释执行字节码,实现数据库操作。...
sqlite-tools-win32-x86-3290000 是一个SQLite数据库工具在Windows 32位系统上的安装包或目录名称。SQLite是一个C库,提供了一个轻量级的磁盘文件数据库,不需要一个单独的服务器进程或操作系统(不需要配置、安装或...
标签“SQLite-1.0.66.0-setup”再次确认了压缩包的内容,它是一个安装程序,专为SQLite的特定版本设计。 压缩包内的唯一文件“SQLite-1.0.66.0-setup.exe”是一个可执行文件,通常在Windows操作系统上运行,用于...
SQLite .NET源码包`sqlite-netFx-source-1.0.86.0`是一个针对.NET平台的SQLite数据库引擎的开源实现,它提供了方便的API接口供.NET开发者使用。这个源码包主要用于学习、研究或者自定义扩展SQLite的功能,以满足特定...
标题"sqlite-netFx46-setup-bundle SQlLite驱动下载"指的是SQLite针对.NET Framework 4.6的安装包。这个安装包包含了SQLite驱动程序,使得.NET开发者可以在他们的应用程序中无缝地集成SQLite数据库。这适用于那些...
总的来说,"sqlite-shell-linux-x86-3080900.zip" 是在Linux环境中管理和操作SQLite数据库的重要工具,它提供了一个直接与数据库交互的界面,使得数据管理变得简单易行。无论你是初学者还是经验丰富的开发者,熟悉并...
在Windows 64位环境下,"sqlite-dll-win64-x64-3350100.zip" 文件代表的是SQLite的动态链接库(DLL)版本,适用于64位(x64)的Windows平台。这里的"3350100"是SQLite的版本号,表示这是到2021年为止的一个较新的...
sqlite-netFx40-setup-bundle-x86-2010-1.0.113.0.exe
sqlitejdbc-v037-nested.jar
标题中的"sqlite-netFx451-static-binary-bundle-x64-2013-1.0.112.0.zip"表明这是一个针对.NET Framework 4.5.1、64位(x64)平台的SQLite静态二进制捆绑包,版本号为1.0.112.0。SQLite是一款开源的关系型数据库管理...