对sqlite3的锁机制简单分析,本人新手,欢迎大家指正。
sqlite用五种锁实现ACID:
1. Nolock:应用处于初始状态
2. Shared:在读操作前获得的锁。(可以有多个应用共享Shared lock)
3. Reserved:表示应用将来有写的意图。(此时其他应用可以获得Shared lock)
4. Pending:表示应用正在因为要执行写操作而等全部Shared lock释放。(此时其他应用不能再获得任何锁)
5. Exclusive:表示应用已经获得锁并在执行写操作。(此时其他应用不能再获得任何锁)
[一次仅有读的事务具有以下锁转换过程]:
Nolock->Shared->Nolock
应用要启动事务读数据,那么首先要尝试获得shared lock,此时如果没有其他应用处于Pending或Exclusive,那么可以顺利完成读任务,并在提交以后释放锁,回到Nolock状态。
[一次有写的事务具有以下锁转换过程]:
Nolock->Shared->Reserved->Pending->Nolock
应用要启动事务写(读写)数据,那么首先要尝试获得shared lock,在获得shared lock以后,可以执行读操作。当应用调用写函数以后,并且还没有执行提交以前,会尝试获得Reserved lock,此时如果没有其他应用处于Reserved,Pending或Exclusive,那么可以进入Reserved状态,注意此时其他应用依然可以获得shared lock。当应用调用commit函数以后,会尝试获得Pendinglock,如果此时没有其他应用处于Pending或Exclusive,那么可以进入Pending状态,直到所有shared lock释放,本应用立即获得Exclusive lock,执行写操作。
四种sqlite锁与linux OS原生锁(文件读/写锁)的对应关系:
B:Reserved是对db文件的一个特定字节(reserved标志字节)加写锁
C:Pending是对db文件的一个特定字节(pending标志字节)加写锁
D:Exclusive是对db文件的部分页加write lock
以下是一些说明:
1.为什么需要Reserved状态?
其中一个原因是为了提高并发度,因为如果事务执行到写操作,但是没有commit,那么此时就阻塞其他读操作是不合适的,所以此时进入Reserved状态,允许读,禁止写。
2.获得Reserved lock时,是否可以释放Shared lock了?
不可以,为了保证ACID,第一个获得Reserved lock的事务必须第一个完成写操作,但是Reserved状态只表示获得了reserved byte的write lock,此时如果其他事务成功申请db page的write lock,那么就违反了ACID,因此需要保留shared lock。
3.
原文链接:https://www.f2er.com/sqlite/201525.html