没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
SQLite教程(十二):锁和并发控制详解教程(十二):锁和并发控制详解
主要介绍了SQLite教程(十二):锁和并发控制详解,本文讲解了锁和并发控制机制概述、文件锁、回滚日志、
数据写入、SQL级别的事务控制等内容,需要的朋友可以参考下
一、概述:一、概述:
在SQLite中,锁和并发控制机制都是由pager_module模块负责处理的,如ACID(Atomic, Consistent, Isolated, and
Durable)。在含有数据修改的事务中,该模块将确保或者所有的数据修改全部提交,或者全部回滚。与此同时,该模块还提供
了一些磁盘文件的内存Cache功能。
事实上,pager_module模块并不关心数据库存储的细节,如B-Tree、编码方式、索引等,它只是将其视为由统一大小(通常
为1024字节)的数据块构成的单一文件,其中每个块被称为一个页(page)。在该模块中页的起始编号为1,即第一个页的索引值
是1,其后的页编号以此类推。
二、文件锁:二、文件锁:
在SQLite的当前版本中,主要提供了以下五种方式的文件锁状态。
1). UNLOCKED:
文件没有持有任何锁,即当前数据库不存在任何读或写的操作。其它的进程可以在该数据库上执行任意的读写操作。此状
态为缺省状态。
2). SHARED:
在此状态下,该数据库可以被读取但是不能被写入。在同一时刻可以有任意数量的进程在同一个数据库上持有共享锁,因
此读操作是并发的。换句话说,只要有一个或多个共享锁处于活动状态,就不再允许有数据库文件写入的操作存在。
3). RESERVED:
假如某个进程在将来的某一时刻打算在当前的数据库中执行写操作,然而此时只是从数据库中读取数据,那么我们就可以
简单的理解为数据库文件此时已经拥有了保留锁。当保留锁处于活动状态时,该数据库只能有一个或多个共享锁存在,即同一
数据库的同一时刻只能存在一个保留锁和多个共享锁。在Oracle中此类锁被称之为预写锁,不同的是Oracle中锁的粒度可以细
化到表甚至到行,因此该种锁在Oracle中对并发的影响程序不像SQLite中这样大。
4). PENDING:
PENDING锁的意思是说,某个进程正打算在该数据库上执行写操作,然而此时该数据库中却存在很多共享锁(读操作),那
么该写操作就必须处于等待状态,即等待所有共享锁消失为止,与此同时,新的读操作将不再被允许,以防止写锁饥饿的现象
发生。在此等待期间,该数据库文件的锁状态为PENDING,在等到所有共享锁消失以后,PENDING锁状态的数据库文件将
在获取排他锁之后进入EXCLUSIVE状态。
5). EXCLUSIVE:
在执行写操作之前,该进程必须先获取该数据库的排他锁。然而一旦拥有了排他锁,任何其它锁类型都不能与之共存。因
此,为了最大化并发效率,SQLite将会最小化排他锁被持有的时间总量。
最后需要说明的是,和其它关系型数据库相比,如MySQL、Oracle等,SQLite数据库中所有的数据都存储在同一文件中,
与此同时,它却仅仅提供了粗粒度的文件锁,因此,SQLite在并发性和伸缩性等方面和其它关系型数据库还是无法比拟的。
由此可见,SQLite有其自身的适用场景,就如在本系列开篇中所说,它和其它关系型数据库之间的互换性还是非常有限的。
三、回滚日志:三、回滚日志:
当一个进程要改变数据库文件的时候,它首先将未改变之前的内容记录到回滚日志文件中。如果SQLite中的某一事务正在
试图修改多个数据库中的数据,那么此时每一个数据库都将生成一个属于自己的回滚日志文件,用于分别记录属于自己的数据
改变,与此同时还要生成一个用于协调多个数据库操作的主数据库日志文件,在主数据库日志文件中将包含各个数据库回滚日
志文件的文件名,在每个回滚日志文件中也同样包含了主数据库日志文件的文件名信息。然而对于无需主数据库日志文件的回
滚日志文件,其中也会保留主数据库日志文件的信息,只是此时该信息的值为空。
我们可以将回滚日志视为"HOT"日志文件,因为它的存在就是为了恢复数据库的一致性状态。当某一进程正在更新数据库
时,应用程序或OS突然崩溃,这样更新操作就不能顺利完成。因此我们可以说"HOT"日志只有在异常条件下才会生成,如果
一切都非常顺利的话,该文件将永远不会存在。
四、数据写入:四、数据写入:
如果某一进程要想在数据库上执行写操作,那么必须先获取共享锁,在共享锁获取之后再获取保留锁。因为保留锁则预示
着在将来某一时刻该进程将会执行写操作,所以在同一时刻只有一个进程可以持有一把保留锁,但是其它进程可以继续持有共
享锁以完成数据读取的操作。如果要执行写操作的进程不能获取保留锁,那么这将说明另一进程已经获取了保留锁。在此种情
况下,写操作将失败,并立即返回SQLITE_BUSY错误。在成功获取保留锁之后,该写进程将创建回滚日志。
在对任何数据作出改变之前,写进程会将待修改页中的原有内容先行写入回滚日志文件中,然而,这些数据发生变化的页
起初并不会直接写入磁盘文件,而是保留在内存中,这样其它进程就可以继续读取该数据库中的数据了。
或者是因为内存中的cache已满,或者是应用程序已经提交了事务,最终,写进程将数据更新到数据库文件中。然而在此之
前,写进程必须确保没有其它的进程正在读取数据库,同时回滚日志中的数据确实被物理的写入到磁盘文件中,其步骤如下:
1). 确保所有的回滚日志数据被物理的写入磁盘文件,以便在出现系统崩溃时可以将数据库恢复到一致的状态。
2). 获取PENDING锁,再获取排他锁,如果此时其它的进程仍然持有共享锁,写入线程将不得不被挂起并等待直到那些共
享锁消失之后,才能进而得到排他锁。
3). 将内存中持有的修改页写出到原有的磁盘文件中。
如果写入到数据库文件的原因是因为cache已满,那么写入进程将不会立刻提交,而是继续对其它页进行修改。但是在接下
来的修改被写入到数据库文件之前,回滚日志必须被再一次写到磁盘中。还要注意的是,写入进程获取到的排他锁必须被一直
资源评论
weixin_38738977
- 粉丝: 6
- 资源: 971
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功