事務和數據庫鎖

? ? 事務定義了一組SQL命令的邊界,這組命令或者作為一個整體被全部執(zhí)行,或者都不執(zhí)行,這稱為數據庫完整性的原子性原則.

事務的范圍

事務由3個命令控制:begin,commit和rollback.begin開始一個事務,begin之后的所有操作都可以取消,如果連接終止前沒有發(fā)出commit,也會被取消.commit提交事務開始所后執(zhí)行的所有操作,rollback還原begin之后所有的操作.

sqlite> begin;

sqlite> delete from test;

sqlite> rollback;

sqlite> select count(*) from test;

比如上面開始了一個事務,先刪除了test表中所有的行,但是有用rollback進行了回滾.在執(zhí)行select時.你會發(fā)現表中沒有發(fā)生任何改變.

默認情況下,SQLite中每條SQL語句自成事務(自動提交模式).也就是說,如果沒有手動使用begin...commit/rollback定義事務的范圍,SQLite默認每條單獨的SQL命令就是begin....commit/rollback的事務.這種情況下,所有成功完成的命令都自動提交.同樣.所有遇見錯誤的命令都回滾,

沖突的解決

違反約束會導致事務的終止.SQLite有其獨特的方法指定不同的方式來處理約束違反,這種功能稱為沖突解決.SQLite提供五種可能的沖突解決方案:

replace:當違反了唯一性約束時,SQLite將造成這種違反的記錄刪除,以插入貨修改的新紀錄代替,SQL繼續(xù)執(zhí)行,且不報錯.

ignore:當違反約束時,SQLite允許命令繼續(xù)執(zhí)行,違反約束的行保持不變.,它之前之后的記錄繼續(xù)修改,且不報錯.

fail:當違反約束時,SQLite終止命令,但是不恢復約束違反之前已經修改的記錄.在約束違法發(fā)生前的改變將保留.

abort(SQLite默認的沖突解決方法):當違反約束時,SQLite恢復命令所做的所有改變并終止命令.abort是最昂貴的沖突解決方案,要求額外的工作.

rollback:當違反約束時,SQLite執(zhí)行回滾.終止當前命令和整個事務.

沖突解決方法可以在SQL明命令中指定,也可以在表和索引的定義中執(zhí)行,沖突解決策略緊跟在insert或者update后面,.并加上前綴or,例如:

update or fail test set id=100 modified='yes';

insert or ignore into from test values('aaron');

也可以在表內定義時,為單個字段指定沖突解決方法,例如:

create temp table cast(name text unique on conflict rollback);

數據庫鎖

在Sqlite中,鎖和事務是緊密聯系的.SQLite采用粗粒度的鎖.當一個連接要寫數據庫時,所有其他的連接被鎖住,知道寫連接結束它的事務.SQLite使用鎖逐步提升機制,為了寫數據庫,連接需要逐級獲得排他鎖.SQLite有5種不同的鎖狀態(tài):未加鎖(unlocked),共享(shared),預留(reserved),未決(pending)和排他(exclusive).每個數據庫連接在同一時刻只能處于其中一個狀態(tài),每種狀態(tài)(未加鎖狀態(tài)除外)都有一種鎖與之對應.SQlite鎖轉換圖如下圖所示:


最初的狀態(tài)是未加鎖狀態(tài),在此狀態(tài)下,連接還沒有訪問數據庫.當連接一個數據庫,甚至已經用begin開始了一個事務時,連接都還處于未加鎖狀態(tài).

未加鎖狀態(tài)的下一個狀態(tài)就是共享狀態(tài).為了能夠從數據庫中讀(而不是寫)數據,連接必須首先進入共享狀態(tài),也就是說,首先要獲得一個共享鎖.多個連接可以同時獲得并保持共享鎖,也就是說,多個連接可以同時從一個數據庫中讀取數據,但是哪怕只有一個共享鎖還沒有釋放,也不允許任何連接寫數據庫.

如果一個連接想要寫數據庫,他必須首先獲得一個預留鎖.一個數據庫同時只能有一個預留鎖,該預留鎖可以與共享鎖共存,他是寫數據庫的第一階段,預留鎖既不阻止其他擁有共享鎖的連接繼續(xù)讀數據可,也不阻止其他連接獲得新的共享鎖.

一旦一個連接獲得了預留鎖,他就可以開始處理數據庫修改的操作了,盡管這些修改只能在緩沖區(qū)中進行,而不是實際寫到磁盤,對讀出內容所做的修改保存在內存緩沖區(qū).當連接想要提交修改(或事務)時,為了得到排他鎖,必須首先將預留鎖提升為未決鎖.獲得未決鎖之后,其他連接就不能在獲得新的共享鎖了,但已經擁有共享所的連接仍然可以繼續(xù)正常讀取數據庫,此時,擁有未決鎖的連接等待其他擁有共享鎖的連接完成工作并釋放共享鎖.

一旦所有的其他的共享鎖都被釋放,擁有未決鎖的連接就可以將其鎖提升為排他鎖,此時就可以自由的對數據庫進行修改,所有以前所緩存的修改都會被寫到數據庫文件中.

事務類型

SQLite有三種不同的事務類型,他們以不同的鎖狀態(tài)啟動事務.事務可以開始于:deferred,immediate和exclusive.事務類型在begin命令中指定:

begin [deferred | immediate | exclusive ] transaction

一個deferred直到必須使用時才獲取鎖.因此,對于延遲事務,begin語句本身不會做什么事情,它從未鎖定狀態(tài)開始.這是默然的情況.

由begin開始的immediate事務在begin執(zhí)行時試圖獲取預留鎖.若果成功,begin immediate 保證沒有其他的連接可以寫數據庫,其他的連接可以繼續(xù)對數據可進行讀操作.預留鎖的其他結果是沒有其他連接能成功啟動begin immedicate 或者begin exclusive 命令,當其他連接執(zhí)行上述命令時,SQLite會返回SQLITE_BUSY錯誤.這時您可以對數據庫進行修改操作,但是調用commit時,如果其他的讀事務還沒有完成,會返回SQLITE_BUSY錯誤,需要等他們執(zhí)行完畢才能提交事務.

exclusive事務會試著獲取對數據庫的排他鎖,一旦成功,exclusive事務保證數據庫中沒有其他的活動連接,所以可對數據庫進行任意的讀寫操作.

基本的準則是:如果使用的數據庫沒有其他連接,用begin就足夠了,但是,如果使用的數據庫有其他也會對數據庫進行寫操作的連接,就得使用begin immedicate 或者begin exclusive 開始事務.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嘴秸,隨后出現的幾起案子剃盾,更是在濱河造成了極大的恐慌造寝,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件占键,死亡現場離奇詭異术吗,居然都是意外死亡擒滑,警方通過查閱死者的電腦和手機骂蓖,發(fā)現死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門积瞒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涯竟,你說我怎么就攤上這事赡鲜】昭幔” “怎么了庐船?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘲更。 經常有香客問我筐钟,道長,這世上最難降的妖魔是什么赋朦? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任篓冲,我火速辦了婚禮,結果婚禮上宠哄,老公的妹妹穿的比我還像新娘壹将。我一直安慰自己,他們只是感情好毛嫉,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布诽俯。 她就那樣靜靜地躺著,像睡著了一般承粤。 火紅的嫁衣襯著肌膚如雪暴区。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天辛臊,我揣著相機與錄音仙粱,去河邊找鬼。 笑死彻舰,一個胖子當著我的面吹牛伐割,可吹牛的內容都是我干的。 我是一名探鬼主播刃唤,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼隔心,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了透揣?” 一聲冷哼從身側響起济炎,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辐真,沒想到半個月后须尚,有當地人在樹林里發(fā)現了一具尸體崖堤,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年耐床,在試婚紗的時候發(fā)現自己被綠了密幔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡撩轰,死狀恐怖胯甩,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情堪嫂,我是刑警寧澤偎箫,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站皆串,受9級特大地震影響淹办,放射性物質發(fā)生泄漏。R本人自食惡果不足惜恶复,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一怜森、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谤牡,春花似錦副硅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至断序,卻和暖如春流纹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背违诗。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工漱凝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诸迟。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓茸炒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阵苇。 傳聞我的和親對象是個殘疾皇子壁公,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容