sqlite的锁的粒度比较粗,是数据库级别的,也就是说即使只是对某个页进行读写操作,sqlite也会封锁整个数据库。这种策略降低了读-写事务和写-写事务间的并发程度,但是大大简化了程序设计,减小了整个程序的大小。所以,sqlite的适用场景为:较少次写入数据,大量、多次读出数据。这也是sqlite作为一款嵌入式数据库的设计初衷。
读、写事务获取锁的过程
sqlite读事务获取锁的过程:UNLOCKED->PENDING->SHARED->进行读取操作
sqlite写事务获取锁的过程:UNLOCKED->PENDING->SHARED->RESERVED->创建回滚日志,在数据库内存页中写入数据,刷新日志文件到磁盘->PENDING->EXCLUSIVE->刷新内存页中的数据到磁盘。
锁的byte
在windows平台,sqlite使用了LockFile(),LockFileEx(),UnlockFile(),UnlockFileEx()这几个API实现锁。锁机制的实现是通过封锁一个在文件1GB处的大小为512B的文件页内的字节实现的。其中:
#define PENDING_BYTE (0x40000000)
#define RESERVED_BYTE (PENDING_BYTE+1)
#define SHARED_FIRST (PENDING_BYTE+2)
#define SHARED_SIZE 510