數(shù)據(jù)庫中的悲觀鎖和樂觀鎖

這兩種類型的鎖都是為了解決更新丟失的問題。

1、什么是丟失更新棚潦?

考慮這個(gè)場景:在一個(gè)web應(yīng)用中,用戶1檢索某表的數(shù)據(jù)行R到編輯頁面膝昆,用戶2也檢索數(shù)據(jù)R到編輯頁面丸边,用戶1修改了R的字段A1叠必,然后提交修改(注意,這里的提交是將用戶編輯頁面的所有字段都更新到數(shù)據(jù)庫妹窖,哪怕該字段沒有變化)纬朝,用戶2這時(shí)修改了R的字段A2,然后執(zhí)行了類似的全量更新提交骄呼。不難發(fā)現(xiàn)共苛,這種情況下,用戶1對于字段A1的修改會(huì)被用戶2的操作覆蓋掉蜓萄。這時(shí)隅茎,我們稱丟失了修改。

有人會(huì)認(rèn)為嫉沽,由于我們在提交修改時(shí)辟犀,也會(huì)將沒有變化的字段也更新,如果只是更新變化的字段就不會(huì)出現(xiàn)這個(gè)問題绸硕。實(shí)際上堂竟,這里的問題在于用戶2在編輯頁面修改數(shù)據(jù)時(shí),所面對的數(shù)據(jù)已經(jīng)不是當(dāng)前數(shù)據(jù)庫中最新的版本玻佩,可能有其它用戶已經(jīng)將某些數(shù)據(jù)做了修改出嘹。考慮在一個(gè)電商系統(tǒng)中咬崔,對于某個(gè)剛支付完成的訂單1税稼,客戶檢索該訂單到編輯頁面,庫管檢索該訂單到編輯頁面刁赦,他們看到的該訂單都是已支付的狀態(tài)娶聘。然后,顧客將訂單的狀態(tài)置為取消甚脉,然后提交修改(這里只提交對狀態(tài)字段的修改),而庫管看到已支付的訂單铆农,然后就將發(fā)貨牺氨,并將訂單狀態(tài)置為了已發(fā)貨。這也是一個(gè)丟失修改的例子墩剖。

這里問題的關(guān)鍵在于后面的用戶在修改時(shí)猴凹,不知道從他查出數(shù)據(jù)到提交更新兩個(gè)操作期間,可能有其它用戶對數(shù)據(jù)做了修改岭皂。這期間的更新沒有被用戶看到郊霎,這種,情況稱為丟失更新爷绘。

2书劝、悲觀鎖和樂觀鎖

為了解決這個(gè)問題进倍,需要用到數(shù)據(jù)庫的鎖機(jī)制,大致兩種思路:悲觀鎖(pessimistic locking)和樂觀鎖(optimistic locking)购对。

2.1 悲觀鎖

悲觀鎖就是在嘗試更新某記錄之前猾昆,先給該記錄加鎖。在上面的例子場景中骡苞,就是在將記錄檢索到編輯頁面時(shí)垂蜗,對該記錄加鎖。之所以叫悲觀鎖解幽,就是因?yàn)檫@個(gè)思路的出發(fā)點(diǎn)比較悲觀贴见,認(rèn)為壞的事情(在數(shù)據(jù)檢索到編輯頁面之后,修改提交之前躲株,會(huì)有其他用戶也修改頁面上的數(shù)據(jù))會(huì)發(fā)生片部。

其實(shí),加鎖很簡單徘溢。比如之前在將記錄載入編輯頁面時(shí)吞琐,用的查詢語句是select cols from table where condition1,那么加鎖后的語句就是select cols from table where condition1 for update nowait然爆。其中站粟,for update代表加鎖,nowait表示如果待加鎖對象上已經(jīng)有鎖曾雕,導(dǎo)致沒法加鎖時(shí)奴烙,立即返回“資源正忙,無法加鎖”的信息剖张,并執(zhí)行結(jié)束切诀。如果沒有指定nowait,則會(huì)一直等著待加鎖對象上當(dāng)前有的鎖釋放搔弄,然后加鎖成功時(shí)幅虑,才會(huì)執(zhí)行結(jié)束。

這樣加鎖之后顾犹,在對該對象持有鎖期間倒庵,對其進(jìn)行更新,并提交炫刷,就能夠保證沒有其他用戶能夠修改加鎖的對象擎宝。這就是悲觀鎖。

2.2 樂觀鎖

相反的浑玛,樂觀鎖的出發(fā)點(diǎn)就是認(rèn)為壞的事情不會(huì)發(fā)生绍申。這樣,在用戶將記錄載入編輯頁面時(shí)不會(huì)進(jìn)行提前加鎖。轉(zhuǎn)而在更新提交時(shí)采用一些技巧极阅,來避免丟失更新胃碾。

可以想象的技巧,大概如下:
(1)給記錄添加版本號標(biāo)識涂屁,每次更新時(shí)對該標(biāo)識加一书在,只有版本號大于數(shù)據(jù)庫中記錄原來的版本號時(shí),記錄才會(huì)被成功更新拆又。
(2)在更新條件中儒旬,添加舊值篩選到where條件,這樣帖族,如果期間有其它用戶更新栈源,會(huì)導(dǎo)致篩選不出記錄,更新失敗竖般。比如甚垦,上面電商的例子中,庫管發(fā)貨的更新腳本可以寫為update table set status=“已發(fā)貨” where condition and status=“已支付”涣雕。這樣艰亮,如果有其它用戶將訂單狀態(tài)改為“取消”,就會(huì)更新0行挣郭,從而避免丟失更新迄埃。
(3)在提交更新前采用select for update(也就是鎖)檢查。這里不是在記錄檢索到修改頁面的時(shí)候加鎖(這時(shí)悲觀鎖的做法)兑障,而是在用戶提交修改的時(shí)候侄非,通過加鎖來檢查該記錄這期間是否被其他用戶修改。如果該記錄沒有變化流译,就提交修改逞怨;如果有變化,就提示用戶記錄狀態(tài)有改變福澡。

有人可能會(huì)認(rèn)為最后一種方式實(shí)際是悲觀鎖的方式叠赦,但實(shí)際上,因?yàn)闆]有提前加鎖革砸,只是更新提交時(shí)加鎖檢查眯搭,所以,也是樂觀鎖业岁。

3寇蚊、適用場景

兩種鎖機(jī)制的適用場景,從它們的名字就能看出來仗岸。悲觀鎖適用于沖突出現(xiàn)概率較高的場景借笙,悲觀鎖應(yīng)用于對象的時(shí)間較長,容易導(dǎo)致阻塞较锡。所以业稼,web應(yīng)用中,用戶讀取數(shù)據(jù)后低散,可能很久才會(huì)提交更新,這樣會(huì)導(dǎo)致鎖長時(shí)間占用熔号,影響效率。所以web應(yīng)用中鸟整,不適合采用悲觀鎖引镊。而樂觀鎖適用于沖突出現(xiàn)概率較低的場景。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篮条,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涉茧,更是在濱河造成了極大的恐慌,老刑警劉巖降瞳,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異除师,居然都是意外死亡扔枫,警方通過查閱死者的電腦和手機(jī)汛聚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門短荐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痕貌,你說我怎么就攤上這事《娉恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵哺徊,是天一觀的道長。 經(jīng)常有香客問我盈滴,道長,這世上最難降的妖魔是什么巢钓? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任谣膳,我火速辦了婚禮,結(jié)果婚禮上继谚,老公的妹妹穿的比我還像新娘烈菌。我一直安慰自己花履,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布济瓢。 她就那樣靜靜地躺著,像睡著了一般旺矾。 火紅的嫁衣襯著肌膚如雪夺克。 梳的紋絲不亂的頭發(fā)上箕宙,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天铺纽,我揣著相機(jī)與錄音,去河邊找鬼陷寝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛凤跑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饶火,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抖僵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤义桂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后慷吊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溉瓶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年谤民,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片触创。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡为牍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碉咆,到底是詐尸還是另有隱情,我是刑警寧澤吟逝,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站励稳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏驹尼。R本人自食惡果不足惜庞呕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一程帕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愁拭,春花似錦亏吝、人聲如沸岭埠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽止喷。三九已至,卻和暖如春乾巧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卧抗。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工鳖粟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人向图。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像榄攀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子吕嘀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容