- 1、本文档共7页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
SQLite入門与分析(五)---PageCache之并发控制
SQLite入门与分析(五)Cache之并发控制写在前面:本节主要谈谈SQLite的锁机制,SQLite是基于锁来实现并发控制的,所以本节的内容实际上是属于事务处理的,但是SQLite的锁机制实现非常的简单而巧妙,所以在这里单独讨论一下。如果真正理解了它,对整个事务的实现也就理解了。而要真正理解SQLite的锁机制,最好方法就是阅读SQLite的源码,所以在阅读本文时,最好能结合源码。SQLite的锁机制很巧妙,尽管在本节中的源码中,我写了很多注释,也是我个人在研究时的一点心得,但是我发现仅仅用言语,似乎不能把问题说清楚,只有通过体会,才能真正理解SQLite的锁机制。好了,下面进入正题。
?
SQLite的并发控制机制是采用加锁的方式,实现非常简单,但也非常的巧妙,本节将对其进行一个详细的解剖。请仔细阅读下图,它可以帮助更好的理解下面的内容。
?
1、RESERVED LOCKRESERVED锁意味着进程将要对数据库进行写操作。某一时刻只能有一个RESERVED Lock,但是RESERVED锁和SHARED锁可以共存,而且可以对数据库加新的SHARED锁。为什么要用RESERVED锁?主要是出于并发性的考虑。由于SQLite只有库级排斥锁(EXCLUSIVE LOCK),如果写事务一开始就上EXCLUSIVE锁,然后再进行实际的数据更新,写磁盘操作,这会使得并发性大大降低。而SQLite一旦得到数据库的RESERVED锁,就可以对缓存中的数据进行修改,而与此同时,其它进程可以继续进行读操作。直到真正需要写磁盘时才对数据库加EXCLUSIVE锁。2、PENDING LOCKPENDING LOCK意味着进程已经完成缓存中的数据修改,并想立即将更新写入磁盘。它将等待此时已经存在的读锁事务完成,但是不允许对数据库加新的SHARED LOCK(这与RESERVED LOCK相区别)。为什么要有PENDING LOCK?主要是为了防止出现写饿死的情况。由于写事务先要获取RESERVED LOCK,所以可能一直产生新的SHARED LOCK,使得写事务发生饿死的情况。3、加锁机制的具体实现
SQLite在pager层获取锁的函数如下:
?
Code//获取一个文件的锁,如果忙则重复该操作,//直到busy?回调用函数返回flase,或者成功获得锁static?int?pager_wait_on_lock(Pager?*pPager,?int?locktype){??int?rc;??assert(?PAGER_SHARED==SHARED_LOCK?);??assert(?PAGER_RESERVED==RESERVED_LOCK?);??assert(?PAGER_EXCLUSIVE==EXCLUSIVE_LOCK?);??if(?pPager-state=locktype?){????rc?=?SQLITE_OK;??}else{???//重复直到获得锁????do?{??????rc?=?sqlite3OsLock(pPager-fd,?locktype);????}while(?rc==SQLITE_BUSY??sqlite3InvokeBusyHandler(pPager-pBusyHandler)?);????????if(?rc==SQLITE_OK?){????????????????//设置pager的状态??????pPager-state?=?locktype;????}??}??return?rc;}
?
Windows下具体的实现如下:
Codestatic?int?winLock(OsFile?*id,?int?locktype){??int?rc?=?SQLITE_OK;????/*?Return?code?from?subroutines?*/??int?res?=?1;???????????/*?Result?of?a?windows?lock?call?*/??int?newLocktype;???????/*?Set?id-locktype?to?this?value?before?exiting?*/??int?gotPendingLock?=?0;/*?True?if?we?acquired?a?PENDING?lock?this?time?*/??winFile?*pFile?=?(winFile*)id;??assert(?pFile!=0?);??TRACE5(LOCK?%d?%d?was?%d(%d)\n,??????????pFile-h,?locktype,?pFile-locktype,?pFil
文档评论(0)