一蟀拷、SQLite3 事務(wù)與鎖狀態(tài)描述
SQLite3總共有三種事務(wù)類(lèi)型:BEGIN [ DEFERRED /IMMEDIATE / EXCLUSIVE ] TRANSCATION胶坠,提供以下五種的文件鎖狀態(tài)缆镣,按鎖的級(jí)別依次是:UNLOCKED / SHARED / RESERVERD / PENDING / EXCLUSIVE。
1). UNLOCKED:無(wú)鎖
文件沒(méi)有持有任何鎖,即當(dāng)前數(shù)據(jù)庫(kù)不存在任何讀或?qū)懙牟僮鳌F渌倪M(jìn)程可以在該數(shù)據(jù)庫(kù)上執(zhí)行任意的讀寫(xiě)操作坦康。此狀態(tài)為缺省狀態(tài)。
2). 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ě)入的操作存在。
3). 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中此類(lèi)鎖被稱(chēng)之為預(yù)寫(xiě)鎖采蚀,不同的是Oracle中鎖的粒度可以細(xì)化到表甚至到行,因此該種鎖在Oracle中對(duì)并發(fā)的影響程序不像SQLite中這樣大承二。
4). PENDING:等待鎖(寫(xiě)等待)
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)伤极。
5). EXCLUSIVE:排它鎖(寫(xiě))
在執(zhí)行寫(xiě)操作之前蛹找,該進(jìn)程必須先獲取該數(shù)據(jù)庫(kù)的排他鎖。然而一旦擁有了排他鎖哨坪,任何其它鎖類(lèi)型都不能與之共存庸疾。因此,為了最大化并發(fā)效率当编,SQLite將會(huì)最小化排他鎖被持有的時(shí)間總量届慈。
二、SQLite3 并發(fā)控制過(guò)程
SQLite的并發(fā)控制機(jī)制是采用加鎖的方式忿偷,實(shí)現(xiàn)非常簡(jiǎn)單金顿,但也非常的巧妙。請(qǐng)仔細(xì)閱讀下圖牵舱,它可以幫助更好的理解下面的內(nèi)容串绩。
當(dāng)執(zhí)行select即讀操作時(shí),需要獲取到SHARED鎖(共享鎖)芜壁,當(dāng)執(zhí)行insert/update/delete操作(即內(nèi)存寫(xiě)操作時(shí))礁凡,需要進(jìn)一步獲取到RESERVERD鎖(保留鎖)高氮,當(dāng)進(jìn)行commit操作(即磁盤(pán)寫(xiě)操作時(shí)),需要進(jìn)一步獲取到EXCLUSIVE鎖(排它鎖)顷牌。
對(duì)于RESERVERD鎖剪芍,sqlite3保證同一時(shí)間只有一個(gè)連接可以獲取到保留鎖,也就是同一時(shí)間只有一個(gè)連接可以寫(xiě)數(shù)據(jù)庫(kù)(內(nèi)存)窟蓝,但是其它連接仍然可以獲取SHARED鎖罪裹,也就是其它連接仍然可以進(jìn)行讀操作(這里可以認(rèn)為寫(xiě)操作只是對(duì)磁盤(pán)數(shù)據(jù)的一份內(nèi)存拷貝進(jìn)行修改,并不影響讀操作)运挫。
對(duì)于EXCLUSIVE鎖状共,是比保留鎖更為嚴(yán)格的一種鎖,在需要把修改寫(xiě)入磁盤(pán)即commit時(shí)需要在保留鎖/未決鎖的基礎(chǔ)上進(jìn)一步獲取到排他鎖谁帕,顧名思義峡继,排他鎖排斥任何其它類(lèi)型的鎖,即使是SHARED鎖也不行匈挖,所以碾牌,在一個(gè)連接進(jìn)行commit時(shí),其它連接是不能做任何操作的(包括讀)儡循。
PENDING鎖(即未決鎖)舶吗,則是比較特殊的一種鎖,它可以允許已獲取到SHARED鎖的事務(wù)繼續(xù)進(jìn)行择膝,但不允許其它連接再獲取SHARED鎖誓琼,當(dāng)已存在的SHARED鎖都被釋放后(事務(wù)執(zhí)行完成),持有未決鎖的事務(wù)就可以獲得commit的機(jī)會(huì)了调榄。sqlite3使用這種鎖來(lái)防止writer starvation(寫(xiě)?zhàn)I死)踊赠。