(十四)并發(fā)控制

??之前在(十三)事務(wù)處理中簡單的介紹了鎖系統(tǒng)陡蝇,并且介紹了由于并發(fā)而產(chǎn)生的種種問題,例如臟讀广匙、幻讀等,因此這里對如何解決這些問題再進(jìn)行一下補(bǔ)充潮剪。


1分唾、悲觀鎖

??在關(guān)系型數(shù)據(jù)庫管理系統(tǒng)里绽乔,悲觀并發(fā)控制是一種并發(fā)控制的方法,它可以阻止一個事務(wù)以影響其他事務(wù)的方式來修改數(shù)據(jù)看疗。悲觀鎖需要使用數(shù)據(jù)庫的鎖機(jī)制两芳,可以從字面理解為這種并發(fā)方式就是很悲觀去枷,每次調(diào)用數(shù)據(jù)的時候都認(rèn)為同時會有其他事務(wù)在修改數(shù)據(jù)是复,因此每次在調(diào)用數(shù)據(jù)前都會先上鎖淑廊,這樣可以防止其他事務(wù)讀取或修改表中的數(shù)據(jù)蒋纬。

??例如:



??此處之所以會出現(xiàn)死鎖坚弱,就是因為執(zhí)行這條語句時已經(jīng)使用了鎖荒叶,

UPDATE tbl_name SET col_name = newValue WHERE id = x;

??因此互相調(diào)用相同的字段造成了死鎖些楣。

??悲觀并發(fā)控制主要用于數(shù)據(jù)爭用激烈的環(huán)境,以及發(fā)生并發(fā)沖突時使用鎖保護(hù)數(shù)據(jù)的成本要低于回滾事務(wù)的成本的環(huán)境中蚕钦。悲觀并發(fā)控制實際上是”先取鎖再訪問”的保守策略鹅很,為數(shù)據(jù)處理的安全提供了保證促煮。但是在效率方面,處理加鎖的機(jī)制會讓數(shù)據(jù)庫產(chǎn)生額外的開銷佑吝,并且會增加產(chǎn)生死鎖的機(jī)會芋忿;另外疾棵,在只讀型事務(wù)處理中由于不會產(chǎn)生沖突,也沒必要使用鎖逆趣,這樣做只能增加系統(tǒng)負(fù)載嗜历,還會降低并行性抖所,因為一個事務(wù)如果鎖定了某行數(shù)據(jù)田轧,其他事務(wù)就必須等待該事務(wù)處理完才可以進(jìn)行處理傻粘。


2帮掉、樂觀鎖

??樂觀鎖相對于悲觀鎖而言,通常會假設(shè)多用戶并發(fā)的事務(wù)在處理時不會彼此互相影響稽莉,各事務(wù)能夠在不產(chǎn)生鎖的情況下處理各自負(fù)責(zé)的數(shù)據(jù)污秆。在提交數(shù)據(jù)更新之前良拼,每個事務(wù)會先檢查在讀取數(shù)據(jù)后充边,有無其他事務(wù)再次修改了該數(shù)據(jù)痛黎。如果有湖饱,那么當(dāng)前正在提交的事務(wù)會進(jìn)行回滾杀捻≈录ィ可以從字面理解為這種并發(fā)方式就是很樂觀垢袱,每次調(diào)用數(shù)據(jù)的時候都認(rèn)為其他事務(wù)不會在同時修改數(shù)據(jù)请契,因此不會上鎖夏醉。

??在處理數(shù)據(jù)時,樂觀鎖并不會使用數(shù)據(jù)庫提供的鎖機(jī)制臣樱,通常樂觀鎖的實現(xiàn)方式是記錄數(shù)據(jù)版本玄捕,即為數(shù)據(jù)增加一個版本標(biāo)識,一般是通過為數(shù)據(jù)庫表增加一個數(shù)字類型的 “version” 字段來實現(xiàn)席吴。當(dāng)讀取數(shù)據(jù)時,將version字段的值一同讀出柬姚,數(shù)據(jù)每更新一次量承,對此version值加1撕捍。當(dāng)提交更新的時候,判斷當(dāng)前version值是否與之前讀出的version值一致狮腿,如果相同缘厢,則予以更新贴硫,否則認(rèn)為是過期數(shù)據(jù)夜畴。

??例如:
??假設(shè)用戶A和用戶B對同一張數(shù)據(jù)表的同一個字段記錄值進(jìn)行修改贪绘,此時用戶A和用戶B從該表中讀取的version值為2均函,用戶A對記錄修改結(jié)束后菱涤,version值增加1如迟,此時該表的version字段的值是3,而用戶B依然按照version值為2進(jìn)行操作玲销,不滿足“提交版本必須大于記錄當(dāng)前版本才能執(zhí)行更新”的樂觀鎖策略贤斜,因此,用戶B的提交被駁回。這樣堕战,就避免了用戶B用基于version值為2的舊數(shù)據(jù)修改的結(jié)果覆蓋用戶A的操作結(jié)果的可能薪介。

??樂觀并發(fā)控制多數(shù)用于數(shù)據(jù)爭用不大道偷、沖突較少的環(huán)境中,此時偶爾回滾事務(wù)的成本會低于讀取數(shù)據(jù)時鎖定數(shù)據(jù)的成本并巍,因此可以獲得比其他并發(fā)控制方法更高的吞吐量换途。


3、MVCC

??多版本并發(fā)控制(Multi-Version Concurrency Control)是為了實現(xiàn)數(shù)據(jù)庫的并發(fā)控制而設(shè)計的一種機(jī)制剃执。大多數(shù)的關(guān)系型數(shù)據(jù)庫都支持MVCC懈息,其突出特點是:讀不加鎖肾档,讀寫不沖突辫继。

??在MVCC中,讀操作可以分成兩類骇两,快照讀和當(dāng)前讀:

  • 快照讀,讀取的是記錄的可見版本(可能是歷史版本配阵,即最新的數(shù)據(jù)可能正在被當(dāng)前執(zhí)行的事務(wù)并發(fā)修改)示血,不會對返回的記錄加鎖;
  • 當(dāng)前讀难审,讀取的是記錄的最新版本,并且會對返回的記錄加鎖黔姜,保證其他事務(wù)不會并發(fā)修改這條記錄。

??在MySQL InnoDB中泻拦,基本的SELECT操作陆错,如

SELECT * FROM tbl_name WHERE xxxx;

??都屬于快照讀绳慎;而屬于當(dāng)前讀的包含以下操作:

SELECT * FROM tbl_name WHERE xxxx LOCK IN SHARE MODE;(共享鎖)
SELECT * FROM tbl_name WHERE xxxx FOR UPDATE;(排他鎖)
INSERT珊楼,UPDATE,DELETE操作(排他鎖)

??可以將MVCC理解為行級鎖的一種妥協(xié)霹购,它在許多情況下避免了使用鎖,同時可以提供更小的開銷。根據(jù)實現(xiàn)的不同催训,它可以允許非阻塞式讀审胚,在寫操作進(jìn)行時只鎖定必要的記錄痘系。

??各個存儲引擎對于MVCC的實現(xiàn)各不相同复唤,下面將通過一個簡化的InnoDB版本的行為來展示MVCC工作原理:
簡單來說呈宇,通過為每一行記錄添加兩個額外的隱藏的值來實現(xiàn)MVCC,這兩個值一個記錄這行數(shù)據(jù)何時被創(chuàng)建,另外一個記錄這行數(shù)據(jù)何時過期(或者被刪除)。但是InnoDB并不存儲這些事件發(fā)生時的實際時間,相反它只存儲這些事件發(fā)生時的系統(tǒng)版本號。這是一個隨著事務(wù)的創(chuàng)建而不斷增長的數(shù)字昔馋。每個事務(wù)在事務(wù)開始時會記錄它自己的系統(tǒng)版本號垄提。每個查詢必須去檢查每行數(shù)據(jù)的版本號與事務(wù)的版本號是否相同审丘。

??以下是在默認(rèn)隔離級別REPEATABLE READ下脓钾,MVCC具體是怎樣實現(xiàn)的:

  • SELECT:
    ??InnoDB只查找版本早于(包含等于)當(dāng)前事務(wù)版本的數(shù)據(jù)行。這保證了不管是事務(wù)開始之前谨胞,或者事務(wù)創(chuàng)建時,或者修改了這行數(shù)據(jù)的時候辜伟,這行數(shù)據(jù)是存在的独郎;這行數(shù)據(jù)的刪除版本必須是未定義的或者比事務(wù)版本要大贪婉,這可以保證在事務(wù)開始之前這行數(shù)據(jù)沒有被刪除。
    ??符合這兩個條件的行可能會被當(dāng)作查詢結(jié)果而返回巩螃。

  • INSERT:
    InnoDB為這個新行記錄當(dāng)前的系統(tǒng)版本號歹叮。

  • DELETE:
    InnoDB將當(dāng)前的系統(tǒng)版本號設(shè)置為這一行的刪除ID。

  • UPDATE:
    InnoDB會寫一個這行數(shù)據(jù)的新拷貝吻商,這個拷貝的版本為當(dāng)前的系統(tǒng)版本號。它同時也會將這個版本號寫到舊行的刪除版本里阳藻。


4夹厌、MVCC與樂觀鎖的區(qū)別

??在了解了MVCC的實現(xiàn)機(jī)制后可能會感覺與樂觀鎖中使用版本號加鎖有相似之處,實際上MVCC可以保證不阻塞地讀到一致的數(shù)據(jù)权她。但是感局,MVCC并沒有對實現(xiàn)細(xì)節(jié)做約束藻雌,在InnoDB引擎下是只對讀無鎖做个,寫操作仍是上鎖的悲觀并發(fā)控制居暖,這也意味著莺奸,InnoDB中只能見到因死鎖和不變性約束而回滾,而不會出現(xiàn)因為寫沖突而回滾的現(xiàn)象略贮;MVCC對數(shù)據(jù)表中的每行數(shù)據(jù)只保留一份讽膏,在更新數(shù)據(jù)時上行級鎖,同時將舊版數(shù)據(jù)寫入undo log闷盔;數(shù)據(jù)表和undo log中行數(shù)據(jù)都記錄著事務(wù)ID迫皱,在檢索時戏阅,只讀取來自當(dāng)前已提交的事務(wù)的行數(shù)據(jù)。這種額外的記錄所帶來的結(jié)果就是對于大多數(shù)查詢來說根本就不需要獲得一個鎖舱痘。MVCC只是簡單地以最快的速度來讀取數(shù)據(jù)离赫,確保只選擇符合條件的行。但其缺點也正是存儲引擎必須為每一行存儲更多的數(shù)據(jù)渊胸,做更多的檢查工作,處理更多的善后操作翎猛。


版權(quán)聲明:歡迎轉(zhuǎn)載,歡迎擴(kuò)散办成,但轉(zhuǎn)載時請標(biāo)明作者以及原文出處搂漠,謝謝合作!             ↓↓↓
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末而克,一起剝皮案震驚了整個濱河市怔毛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碎绎,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筋帖,死亡現(xiàn)場離奇詭異冤馏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)代箭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乙帮,“玉大人极景,你說我怎么就攤上這事〈鞫福” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵异吻,是天一觀的道長喜庞。 經(jīng)常有香客問我,道長雷猪,這世上最難降的妖魔是什么晰房? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮与境,結(jié)果婚禮上猖吴,老公的妹妹穿的比我還像新娘。我一直安慰自己海蔽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布拗引。 她就那樣靜靜地躺著刑然,像睡著了一般。 火紅的嫁衣襯著肌膚如雪怔软。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天括改,我揣著相機(jī)與錄音家坎,去河邊找鬼。 笑死虱疏,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的对粪。 我是一名探鬼主播装蓬,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼儡遮!你這毒婦竟也來了暗赶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤爱榔,失蹤者是張志新(化名)和其女友劉穎糙及,沒想到半個月后筛欢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡柱搜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年剥险,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片健爬。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娜遵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慨仿,我是刑警寧澤纳胧,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站鼎姊,受9級特大地震影響相赁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钮科,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一绵脯、第九天 我趴在偏房一處隱蔽的房頂上張望佳励。 院中可真熱鬧蛆挫,春花似錦、人聲如沸瞧剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捉撮。三九已至妇垢,卻和暖如春巾遭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背迎罗。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工片仿, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厢岂。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓蠢棱,卻偏偏與公主長得像俊犯,于是被迫代替她去往敵國和親分瘦。 傳聞我的和親對象是個殘疾皇子酥筝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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