SQLite学习手册(锁和并发控制) (二)

2014-11-24 10:45:53 · 作者: · 浏览: 1
作。因此只有在成功删除主日志文件之后,我们才可以认为该事务成功完成。
9). 删除每个数据库各自的日志文件。
10).从所有数据库中删除掉排他锁和PENDING锁。

最后需要说明的是,在SQLite2中,如果多个进程正在从数据库中读取数据,也就是说该数据库始终都有读操作发生,即在每一时刻该数据库都持有至少一把共享锁,这样将会导致没有任何进程可以执行写操作,因为在数据库持有读锁的时候是无法获取写锁的,我们将这种情形称为"写饥饿"。在SQLite3中,通过使用PENDING锁则有效的避免了"写饥饿"情形的发生。当某一进程持有PENDING锁时,已经存在的读操作可以继续进行,直到其正常结束,但是新的读操作将不会再被SQLite接受,所以在已有的读操作全部结束后,持有PENDING锁的进程就可以被激活并试图进一步获取排他锁以完成数据的修改操作。

五、SQL级别的事务控制:

SQLite3在实现上确实针对锁和并发控制做出了一些精巧的变化,特别是对于事务这一SQL语言级别的特征。在缺省情况下,SQLite3会将所有的SQL操作置于antocommit模式下,这样所有针对数据库的修改操作都会在SQL命令执行结束后被自动提交。在SQLite中,SQL命令"BEGIN TRANSACTION"用于显式的声明一个事务,即其后的SQL语句在执行后都不会自动提交,而是需要等到SQL命令"COMMIT"或"ROLLBACK"被执行时,才考虑提交还是回滚。由此可以推断出,在BEGIN命令被执行后并没有立即获得任何类型的锁,而是在执行第一个SELECT语句时才得到一个共享锁,或者是在执行第一个DML语句时才获得一个保留锁。至于排它锁,只有在数据从内存写入磁盘时开始,直到事务提交或回滚之前才能持有排它锁。
如果多个SQL命令在同一个时刻同一个数据库连接中被执行,autocommit将会被延迟执行,直到最后一个命令完成。比如,如果一个SELECT语句正在被执行,在这个命令执行期间,需要返回所有检索出来的行记录,如果此时处理结果集的线程因为业务逻辑的需要被暂时挂起并处于等待状态,而其它的线程此时或许正在该连接上对该数据库执行INSERT、UPDATE或DELETE命令,那么所有这些命令作出的数据修改都必须等到SELECT检索结束后才能被提交。

这是该系列中最后一篇关于SQLite理论与应用方面的博客了,后面将发布两篇关于如何利用SQLite 编程的博客,其中还将包含四个典型的应用代码示例,望大家继续保持关注。


作者 Stephen_Liu