
一、SQLite3 事務(wù)與鎖狀態(tài)描述
SQLite3總共有三種事務(wù)類型:BEGIN [ DEFERRED /IMMEDIATE / EXCLUSIVE ] TRANSCATION,提供以下五種的文件鎖狀態(tài),按鎖的級別依次是:UNLOCKED / SHARED / RESERVERD / PENDING / EXCLUSIVE。
1). UNLOCKED:無鎖
文件沒有持有任何鎖,即當(dāng)前數(shù)據(jù)庫不存在任何讀或?qū)懙牟僮?。其它的進(jìn)程可以在該數(shù)據(jù)庫上執(zhí)行任意的讀寫操作。此狀態(tài)為缺省狀態(tài)。
2). SHARED:共享鎖
在此狀態(tài)下,該數(shù)據(jù)庫可以被讀取但是不能被寫入。在同一時刻可以有任意數(shù)量的進(jìn)程在同一個數(shù)據(jù)庫上持有共享鎖,因此讀操作是并發(fā)的。換句話說,只要有一個或多個共享鎖處于活動狀態(tài),就不再允許有數(shù)據(jù)庫文件寫入的操作存在。
3). RESERVED:保留鎖
假如某個進(jìn)程在將來的某一時刻打算在當(dāng)前的數(shù)據(jù)庫中執(zhí)行寫操作,然而此時只是從數(shù)據(jù)庫中讀取數(shù)據(jù),那么我們就可以簡單的理解為數(shù)據(jù)庫文件此時已經(jīng)擁有了保留鎖。當(dāng)保留鎖處于活動狀態(tài)時,該數(shù)據(jù)庫只能有一個或多個共享鎖存在,即同一數(shù)據(jù)庫的同一時刻只能存在一個保留鎖和多個共享鎖。
在Oracle中此類鎖被稱之為預(yù)寫鎖,不同的是Oracle中鎖的粒度可以細(xì)化到表甚至到行,因此該種鎖在Oracle中對并發(fā)的影響程序不像SQLite中這樣大。
4). PENDING:等待鎖(寫等待)
PENDING鎖的意思是說,某個進(jìn)程正打算在該數(shù)據(jù)庫上執(zhí)行寫操作,然而此時該數(shù)據(jù)庫中卻存在很多共享鎖(讀操作),那么該寫操作就必須處于等待狀態(tài),即等待所有共享鎖消失為止,與此同時,新的讀操作將不再被允許,以防止寫鎖饑餓的現(xiàn)象發(fā)生。在此等待期間,該數(shù)據(jù)庫文件的鎖狀態(tài)為PENDING,在等到所有共享鎖消失以后,PENDING鎖狀態(tài)的數(shù)據(jù)庫文件將在獲取排他鎖之后進(jìn)入EXCLUSIVE狀態(tài)。
5). EXCLUSIVE:排它鎖(寫)
在執(zhí)行寫操作之前,該進(jìn)程必須先獲取該數(shù)據(jù)庫的排他鎖。然而一旦擁有了排他鎖,任何其它鎖類型都不能與之共存。因此,為了最大化并發(fā)效率,SQLite將會最小化排他鎖被持有的時間總量。
二、SQLite3 并發(fā)控制過程
SQLite的并發(fā)控制機(jī)制是采用加鎖的方式,實現(xiàn)非常簡單,但也非常的巧妙。請仔細(xì)閱讀下圖,它可以幫助更好的理解下面的內(nèi)容。
當(dāng)執(zhí)行select即讀操作時,需要獲取到SHARED鎖(共享鎖),當(dāng)執(zhí)行insert/update/delete操作(即內(nèi)存寫操作時),需要進(jìn)一步獲取到RESERVERD鎖(保留鎖),當(dāng)進(jìn)行commit操作(即磁盤寫操作時),需要進(jìn)一步獲取到EXCLUSIVE鎖(排它鎖)。
對于RESERVERD鎖,sqlite3保證同一時間只有一個連接可以獲取到保留鎖,也就是同一時間只有一個連接可以寫數(shù)據(jù)庫(內(nèi)存),但是其它連接仍然可以獲取SHARED鎖,也就是其它連接仍然可以進(jìn)行讀操作(這里可以認(rèn)為寫操作只是對磁盤數(shù)據(jù)的一份內(nèi)存拷貝進(jìn)行修改,并不影響讀操作)。
對于EXCLUSIVE鎖,是比保留鎖更為嚴(yán)格的一種鎖,在需要把修改寫入磁盤即commit時需要在保留鎖/未決鎖的基礎(chǔ)上進(jìn)一步獲取到排他鎖,顧名思義,排他鎖排斥任何其它類型的鎖,即使是SHARED鎖也不行,所以,在一個連接進(jìn)行commit時,其它連接是不能做任何操作的(包括讀)。
PENDING鎖(即未決鎖),則是比較特殊的一種鎖,它可以允許已獲取到SHARED鎖的事務(wù)繼續(xù)進(jìn)行,但不允許其它連接再獲取SHARED鎖,當(dāng)已存在的SHARED鎖都被釋放后(事務(wù)執(zhí)行完成),持有未決鎖的事務(wù)就可以獲得commit的機(jī)會了。sqlite3使用這種鎖來防止writer starvation(寫?zhàn)I死)。