SQL 多個事務(wù)并發(fā)時可能遇到的問題

Reference

事務(wù)并發(fā)的可能問題與其解決方案
臟讀湾戳、幻讀贤旷、不可重復(fù)讀和丟失更新
數(shù)據(jù)庫并發(fā)事務(wù)存在的問題(臟讀、不可重復(fù)讀砾脑、幻讀等)
對于臟讀幼驶,不可重復(fù)讀,幻讀的一點(diǎn)理解韧衣,看懂紅字很關(guān)鍵
MySQL 四種事務(wù)隔離級的說明
15.7.2.1 Transaction Isolation Levels
MySQL Innodb 事務(wù)隔離級別
【漫畫】如何給新來的師妹解釋什么是數(shù)據(jù)庫的臟讀盅藻、不可重復(fù)讀和幻讀

多個事務(wù)并發(fā)時可能遇到的問題

  1. Lost Update 更新丟失 (兩類)
    a. 第一類更新丟失,回滾覆蓋
    b. 第二類更新丟失畅铭,提交覆蓋
  2. Read Phenomena 讀現(xiàn)象 (三種)
    a. Dirty Reads 臟讀
    b. Non-Repeatable Reads 不可重復(fù)讀
    c. Phantom Reads 幻讀

更新丟失

第一類更新丟失氏淑,回滾覆蓋

定義

撤消一個事務(wù)時,在該事務(wù)內(nèi)的寫操作要回滾硕噩,把其它已提交的事務(wù)寫入的數(shù)據(jù)覆蓋了假残。

解釋
實(shí)例
時間 取款事務(wù) A 轉(zhuǎn)賬事務(wù) B
T1 開始事務(wù)
T2 開始事務(wù)
T3 讀余額為 1000
T4 取出 100, 余額改為 900
T5 讀余額為 1000
T6 匯入 100炉擅, 余額改為 1100
T7 提交事務(wù)辉懒, 余額定位 1100
T8 撤銷事務(wù), 余額改回 1000 -
T9 最終余額為 1000坑资,更新丟失 -

寫操作沒加 “持續(xù) - X 鎖”耗帕,沒能阻止事務(wù) B 寫,發(fā)生了回滾覆蓋袱贮。

第二類更新丟失仿便,提交覆蓋

定義

提交一個事務(wù)時,寫操作依賴于事務(wù)內(nèi)讀到的數(shù)據(jù)攒巍,讀發(fā)生在其他事務(wù)提交前嗽仪,寫發(fā)生在其他事務(wù)提交后,把其他已提交的事務(wù)寫入的數(shù)據(jù)覆蓋了柒莉。這是不可重復(fù)讀的特例闻坚。

解釋
實(shí)例
時間 取款事務(wù) A 轉(zhuǎn)賬事務(wù) B
T1 開始事務(wù)
T2 開始事務(wù)
T3 讀余額為 1000
T4 讀余額為 1000
T5 取出 100, 余額改為 900
T6 提交事務(wù)兢孝, 余額定位 900
T7 匯入 100窿凤,余額改為 1100 -
T8 提交事務(wù)仅偎,余額定為 1100 -
T9 最終余額為 1100,更新丟失 -

寫操作加了 “持續(xù) - X 鎖”雳殊, 讀操作加了 “臨時 - S 鎖”橘沥,沒能阻止事務(wù) B 寫,發(fā)生了提交覆蓋夯秃。

Read Phenomena 讀現(xiàn)象

Dirty Reads 臟讀

定義

一個事務(wù)讀到了另一個未提交的事務(wù)寫的數(shù)據(jù)座咆。

針對未提交數(shù)據(jù)

解釋

當(dāng)一個事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改仓洼,而這種修改還沒有提交(commit)到數(shù)據(jù)庫中介陶,這時,另外一個事務(wù)也訪問這個數(shù)據(jù)色建,然后使用了這個數(shù)據(jù)哺呜。因?yàn)檫@個數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個事務(wù)讀到的這個數(shù)據(jù)是臟數(shù)據(jù)箕戳,依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的弦牡。

實(shí)例
時間 取款事務(wù) A 轉(zhuǎn)賬事務(wù) B
T1 開始事務(wù)
T2 開始事務(wù)
T3 讀余額為 1000 查詢賬戶余額為 1000
T4 取出 500, 余額改為 500
T5 讀余額為 500 (臟讀)
T6 撤銷事務(wù)漂羊,余額恢復(fù)為 1000
T7 匯入 100驾锰,余額改為 600 -
T8 提交事務(wù) -
T9 最終余額為 600,丟失 400 -
解決

修改時加排他鎖走越,直到事務(wù)提交后才釋放椭豫,讀取時加共享鎖,讀取完釋放事務(wù) A 讀取數(shù)據(jù)時加上共享鎖后(這樣在事務(wù) A 讀取數(shù)據(jù)的過程中旨指,其他事務(wù)就不會修改該數(shù)據(jù))赏酥,不允許任何事務(wù)操作該數(shù)據(jù),只能讀取谆构,之后 A 如果有更新操作裸扶,那么會轉(zhuǎn)換為排他鎖,其他事務(wù)更無權(quán)參與進(jìn)來讀寫搬素,這樣就防止了臟讀問題呵晨。但是當(dāng)事務(wù) A 讀取數(shù)據(jù)過程中,有可能其他事務(wù)也讀取了該數(shù)據(jù)熬尺,讀取完畢后共享鎖釋放摸屠,此時事務(wù) A 修改數(shù)據(jù),修改完畢提交事務(wù)粱哼,其他事務(wù)再次讀取數(shù)據(jù)時候發(fā)現(xiàn)數(shù)據(jù)不一致季二,就會出現(xiàn)不可重復(fù)讀問題,所以這樣不能夠避免不可重復(fù)讀問題。

Non-Repeatable Reads 不可重復(fù)讀

定義

一個事務(wù)中兩次讀同一行數(shù)據(jù)胯舷,可是這兩次讀到的數(shù)據(jù)不一樣刻蚯。

針對其他提交前后,讀取數(shù)據(jù)本身的對比
不可重復(fù)讀重點(diǎn)在修改

解釋

在數(shù)據(jù)庫訪問中桑嘶,一個事務(wù)范圍內(nèi)兩個相同的查詢卻返回了不同數(shù)據(jù)芦倒。這是由于查詢時系統(tǒng)中其他事務(wù)修改的提交而引起的。比如事務(wù)T1讀取某一數(shù)據(jù)不翩,事務(wù)T2讀取并修改了該數(shù)據(jù),T1為了對讀取值進(jìn)行檢驗(yàn)而再次讀取該數(shù)據(jù)麻裳,便得到了不同的結(jié)果口蝠。

實(shí)例
時間 取款事務(wù) A 轉(zhuǎn)賬事務(wù) B
T1 開始事務(wù)
T2 讀取余額為 1000
T3 開始事務(wù)
T4 取出 500, 余額改為 500
T5 提交事務(wù)
T6 再次讀取余額為 500 (不可重復(fù)讀取)
解決

讀取數(shù)據(jù)時加共享鎖津坑,寫數(shù)據(jù)時加排他鎖妙蔗,都是事務(wù)提交才釋放鎖。讀取時候不允許其他事物修改該數(shù)據(jù)疆瑰,不管數(shù)據(jù)在事務(wù)過程中讀取多少次眉反,數(shù)據(jù)都是一致的,避免了不可重復(fù)讀問題穆役。

Phantom Reads 幻讀

定義

同一個事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣(比如增加了或者減少了行記錄)寸五。

針對其他提交前后,讀取數(shù)據(jù)條數(shù)的對比
幻讀是不可重復(fù)讀的一種特殊場景耿币。
幻讀重點(diǎn)在新增或刪除

解釋

比如同一個事務(wù)A內(nèi)第一次查詢時候有n條記錄梳杏,但是第二次同等條件下查詢卻又n+1條記錄,這就好像產(chǎn)生了幻覺淹接。
沒有范圍鎖

實(shí)例
時間 取款事務(wù) A 轉(zhuǎn)賬事務(wù) B
T1 開始事務(wù)
T2 查詢交易記錄次數(shù)
T3 開始事務(wù)
T4 新增交易記錄
T5 提交事務(wù)
T6 再次查詢交易記錄次數(shù) (幻讀) -
解決

實(shí)行 Serializable 隔離模式: 采用范圍鎖 RangeS - RangeS-S Mode十性,鎖定檢索范圍為只讀,這樣就避免了幻讀問題塑悼。


數(shù)據(jù)庫通過鎖機(jī)制解決并發(fā)訪問的問題劲适。根據(jù)鎖定對象不同:分為行級鎖和表級鎖;根據(jù)并發(fā)事務(wù)鎖定的關(guān)系上看:分為共享鎖定和獨(dú)占鎖定厢蒜,共享鎖定會防止獨(dú)占鎖定但允許其他的共享鎖定霞势。而獨(dú)占鎖定既防止共享鎖定也防止其他獨(dú)占鎖定。為了更改數(shù)據(jù)斑鸦,數(shù)據(jù)庫必須在進(jìn)行更改的行上施加行獨(dú)占鎖定支示,insert、update鄙才、delete和selsct for update語句都會隱式采用必要的行鎖定颂鸿。

但是直接使用鎖機(jī)制管理是很復(fù)雜的,基于鎖機(jī)制攒庵,數(shù)據(jù)庫給用戶提供了不同的事務(wù)隔離級別嘴纺,只要設(shè)置了事務(wù)隔離級別败晴,數(shù)據(jù)庫就會分析事務(wù)中的sql語句然后自動選擇合適的鎖。

事務(wù)的隔離級別和數(shù)據(jù)庫并發(fā)性是成反比的栽渴,隔離級別越高尖坤,并發(fā)性越低。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闲擦,一起剝皮案震驚了整個濱河市慢味,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墅冷,老刑警劉巖纯路,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異寞忿,居然都是意外死亡驰唬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門腔彰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叫编,“玉大人,你說我怎么就攤上這事霹抛〈暧猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵杯拐,是天一觀的道長恃逻。 經(jīng)常有香客問我,道長藕施,這世上最難降的妖魔是什么寇损? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮裳食,結(jié)果婚禮上矛市,老公的妹妹穿的比我還像新娘。我一直安慰自己诲祸,他們只是感情好浊吏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著救氯,像睡著了一般找田。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上着憨,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天墩衙,我揣著相機(jī)與錄音,去河邊找鬼。 笑死漆改,一個胖子當(dāng)著我的面吹牛心铃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挫剑,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼去扣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了樊破?” 一聲冷哼從身側(cè)響起愉棱,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哲戚,沒想到半個月后奔滑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惫恼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澳盐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祈纯。...
    茶點(diǎn)故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叼耙,靈堂內(nèi)的尸體忽然破棺而出腕窥,到底是詐尸還是另有隱情,我是刑警寧澤筛婉,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布簇爆,位于F島的核電站,受9級特大地震影響爽撒,放射性物質(zhì)發(fā)生泄漏入蛆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一硕勿、第九天 我趴在偏房一處隱蔽的房頂上張望哨毁。 院中可真熱鬧,春花似錦源武、人聲如沸扼褪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽话浇。三九已至,卻和暖如春闹究,著一層夾襖步出監(jiān)牢的瞬間幔崖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岖瑰,地道東北人叛买。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蹋订,于是被迫代替她去往敵國和親率挣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評論 2 349