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ā)時可能遇到的問題
- Lost Update 更新丟失 (兩類)
a. 第一類更新丟失,回滾覆蓋
b. 第二類更新丟失畅铭,提交覆蓋 - 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ā)性越低。