《SQLite學(xué)習(xí)筆記(二)》要點(diǎn):
本文介紹了SQLite學(xué)習(xí)筆記(二),希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
代碼下載
git clone git@github.com:mackyle/sqlite.git
SQLite的鎖
五種鎖狀態(tài):
UNLOCKED:
文件沒(méi)有持有任何鎖,即當(dāng)前數(shù)據(jù)庫(kù)不存在任何讀或?qū)懙牟僮?其它的進(jìn)程可以在該數(shù)據(jù)庫(kù)上執(zhí)行任意的讀寫(xiě)操作.此狀態(tài)為缺省狀態(tài).
SHARED:
在此狀態(tài)下,該數(shù)據(jù)庫(kù)可以被讀取但是不能被寫(xiě)入.在同一時(shí)刻可以有任意數(shù)量的進(jìn)程在同一個(gè)數(shù)據(jù)庫(kù)上持有共享鎖,因此讀操作是并發(fā)的.換句話說(shuō),只要有一個(gè)或多個(gè)共享鎖處于活動(dòng)狀態(tài),就不再允許有數(shù)據(jù)庫(kù)文件寫(xiě)入的操作存在.
RESERVED:
假如某個(gè)進(jìn)程在將來(lái)的某一時(shí)刻打算在當(dāng)前的數(shù)據(jù)庫(kù)中執(zhí)行寫(xiě)操作,然而此時(shí)只是從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù),那么我們就可以簡(jiǎn)單的理解為數(shù)據(jù)庫(kù)文件此時(shí)已經(jīng)擁有了保存鎖.當(dāng)保存鎖處于活動(dòng)狀態(tài)時(shí),該數(shù)據(jù)庫(kù)只能有一個(gè)或多個(gè)共享鎖存在,即同一數(shù)據(jù)庫(kù)的同一時(shí)刻只能存在一個(gè)保存鎖和多個(gè)共享鎖.在Oracle中此類鎖被稱之為預(yù)寫(xiě)鎖,不同的是Oracle中鎖的粒度可以細(xì)化到表甚至到行,因此該種鎖在Oracle中對(duì)并發(fā)的影響程序不像SQLite中這樣大.
PENDING:
PENDING鎖的意思是說(shuō),某個(gè)進(jìn)程正打算在該數(shù)據(jù)庫(kù)上執(zhí)行寫(xiě)操作,然而此時(shí)該數(shù)據(jù)庫(kù)中卻存在很多共享鎖(讀操作),那么該寫(xiě)操作就必須處于等待狀態(tài),即等待所有共享鎖消失為止,與此同時(shí),新的讀操作將不再被允許,以防止寫(xiě)鎖饑餓的現(xiàn)象發(fā)生.在此等待期間,該數(shù)據(jù)庫(kù)文件的鎖狀態(tài)為PENDING,在比及所有共享鎖消失以后,PENDING鎖狀態(tài)的數(shù)據(jù)庫(kù)文件將在獲取排他鎖之后進(jìn)入EXCLUSIVE狀態(tài).
EXCLUSIVE:
在執(zhí)行寫(xiě)操作之前,該進(jìn)程必需先獲取該數(shù)據(jù)庫(kù)的排他鎖.然而一旦擁有了排他鎖,任何其它鎖類型都不能與之共存.因此,為了最大化并發(fā)效率,SQLite將會(huì)最小化排他鎖被持有的時(shí)間總量.
鎖狀態(tài)轉(zhuǎn)換圖:
一個(gè)事務(wù)可以在UNLOCKED、RESERVED或EXCLUSIVE三種狀態(tài)下開(kāi)始.默認(rèn)情況下在UNLOCKED時(shí)開(kāi)始.
白色框中的UNLOCKED、PENDING、SHARED和 RESERVED可以在一個(gè)數(shù)據(jù)庫(kù)的同一時(shí)刻存在.
從灰色的PENDING開(kāi)始,事情就變得嚴(yán)格起來(lái),意味著事務(wù)想得到排它鎖(EXCLUSIVE)(注意與白色框中的區(qū)別).
讀事務(wù)
db = open('foods.db')
db.exec('BEGIN')
db.exec('SELECT * FROM episodes')
db.exec('SELECT * FROM episodes')
db.exec('COMMIT')
db.close()
由于顯式地使用了BEGIN和COMMIT,兩個(gè)SELECT命令在一個(gè)事務(wù)下執(zhí)行.第一個(gè)exec()執(zhí)行時(shí),連接處于SHARED,然后第二個(gè)exec()執(zhí)行.當(dāng)事務(wù)提交時(shí),連接又從SHARED回到UNLOCKED狀態(tài).
相應(yīng)的狀態(tài)真正的變化過(guò)程為:UNLOCKED→PENDING(1)→PENDING、SHARED(2)→SHARED(6)→UNLOCKED
如果沒(méi)有BEGIN和COMMIT兩行,兩個(gè)SELECT都運(yùn)行于自動(dòng)提交狀態(tài)
相應(yīng)的狀態(tài)真正的變化過(guò)程為:UNLOCKED→PENDING→SHARED→UNLOCKED→PENDING→SHARED→UNLOCKED
寫(xiě)事務(wù)
類型 操作 鎖信息 說(shuō)明 讀事務(wù) begin 不持有鎖 select c1 from user where id =1 Lock:Pending(Read)Lock:Shared(Read)Unlock:Pending 獲取Shared讀鎖前,必要先獲取Pending共享鎖通過(guò)這種方式與寫(xiě)事務(wù)互斥. commit UnLock:Shared 寫(xiě)事務(wù) begin 不持有鎖 Update c1=c1+1 where id =1 Lock: Pending(Read)Lock:SharedUnlock:PendingLock:Reserved(Write) 先獲取Shared讀鎖,然后獲取Reserved排它鎖,阻止其它寫(xiě)事務(wù) commit Lock:Pending(Write)Lock:Exclusive(Write)Unlock: PendingUnlock:Exclusive(Write) 獲取Pending的排它鎖,阻止新的讀事務(wù),最后上排它鎖,阻止所有讀事務(wù),讀寫(xiě)不能并發(fā)Pending鎖方式好處是,減少寫(xiě)?zhàn)I死的幾率. WAL機(jī)制
WAL日志文件鎖
WAL日志鎖實(shí)質(zhì)是鎖wal-index文件的區(qū)域,根據(jù)不同的鎖類型,將wal-index文件的不同區(qū)域劃定義成不同的鎖,主要有讀鎖,寫(xiě)鎖,檢查點(diǎn)鎖.WAL模式下,最新的數(shù)據(jù)位于日志文件中,無(wú)論是讀事務(wù)還是寫(xiě)事務(wù)都必要持有WAL_READ_LOCK的讀鎖,因?yàn)樗鼈兌急匾@取最新的事務(wù)點(diǎn).因此,做檢查點(diǎn)時(shí),可以通過(guò)對(duì)WAL_READ_LOCK位置(124-127)上鎖,來(lái)確定檢查點(diǎn)必要等待還是停止推進(jìn).同時(shí)我們也可以看到,對(duì)于DB文件,讀寫(xiě)事務(wù)都只必要對(duì)DB文件上讀鎖,對(duì)于WAL日志文件,WAL_READ_LOCK和WAL_WRITE_LOCK位于不同的位置,讀寫(xiě)相互不影響,所以讀寫(xiě)不互斥.
類型 操作 鎖信息 說(shuō)明 讀事務(wù) begin 不持有鎖 select c1 from user where id =1 DB文件:Lock:Pending(Read)Lock:SharedUnlock:PendingWAL文件:Lock:WAL_READ_LOCK(Read) 除了獲取DB文件鎖,還必要獲取WAL鎖,得到最新提交事務(wù)的位點(diǎn).若有事務(wù)再作檢查點(diǎn),必要重試多次. commit Unlock:WAL_READ_LOCKUnlock:Shared 寫(xiě)事務(wù) begin 不持有鎖 Update c1=c1+1 where id =1 DB文件:Lock: Pending-ReadLock:Shared(Read)Unlock:PendingWAL文件:Lock:WAL_READ_LOCK(Read)Lock:WAL_WRITE_LOCK(Write) 通過(guò)EXCLUSIVE-WRITE-LOCK控制寫(xiě)寫(xiě)并發(fā)由于不操作DB文件,因此不存在讀寫(xiě)沖突,讀寫(xiě)可以并發(fā). commit WAL文件:Lock:SHARED-READ-LOCKUnlock:WAL_READ_LOCK(Read)Unlock: WAL_WRITE_LOCK(Write)DB文件:Unlock:Shared 獲取SHARED-READ-LOCK目的是為了獲取最新提交日志的位點(diǎn) checkpoint WAL文件:Lock:WAL_CKPT_LOCK(write)Lock:WAL_READ_LOCK(write)UnLock:WAL_READ_LOCKUnLock:WAL_CKPT_LOCK EXCLUSIVE-CKPT-LOCK保證只有一個(gè)寫(xiě)事務(wù)做檢查點(diǎn);WAL_READ_LOCK阻止讀寫(xiě)事務(wù).
維易PHP培訓(xùn)學(xué)院每天發(fā)布《SQLite學(xué)習(xí)筆記(二)》等實(shí)戰(zhàn)技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養(yǎng)人才。
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/9156.html