怎么理解數(shù)據(jù)庫事務隔離級別及臟讀、不可重復讀、幻讀
發(fā)表時間:2023-07-10 來源:明輝站整理相關軟件相關文章人氣:
[摘要]本篇文章給大家?guī)淼膬?nèi)容是關于如何理解數(shù)據(jù)庫事務隔離級別及臟讀、不可重復讀、幻讀,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。一、數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素1.1ACID原則...
本篇文章給大家?guī)淼膬?nèi)容是關于如何理解數(shù)據(jù)庫事務隔離級別及臟讀、不可重復讀、幻讀,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
一、數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素
1.1ACID原則。
??ACID原則是數(shù)據(jù)庫事務正常執(zhí)行的四個基本要素,分別指原子性、一致性、獨立性及持久性。
??事務的原子性(Atomicity)是指一個事務要么全部執(zhí)行,要么不執(zhí)行,也就是說一個事務不可能只執(zhí)行了一半就停止了,比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢。不可能劃了卡,而錢卻沒出來,這兩步必須同時完成.要么就不完成。
??事務的一致性(Consistency)是指事務的運行并不改變數(shù)據(jù)庫中數(shù)據(jù)的一致性。例如,完整性約束了a+b=10,一個事務改變了a,那么b也應該隨之改變。或者說,A給B轉賬300元錢,那么A的賬戶就必須是減少300元錢,B的賬戶就必須是增加300元錢,不能說是增加或減少了如200元錢等,這里符合事務的原子性,但是不符合事務的一致性。往實際業(yè)務中沒有這么簡單,往是類似買東西扣庫存這類的邏輯,主表里有庫存,庫存表里有庫存,SKU表里還有,然后就因為設計缺陷,就算加了事務還是出現(xiàn)了超賣、SKU庫存對不上總庫存的問題,這個就是一致性不滿足的了。
??獨立性(Isolation):事務的獨立性也有稱作隔離性,是指兩個以上的事務不會出現(xiàn)交錯執(zhí)行的狀態(tài),因為這樣可能會導致數(shù)據(jù)不一致。
??持久性(Durability):一旦事務提交或者回滾,這個狀態(tài)都要持久化到數(shù)據(jù)庫中,不考慮隔離性會出現(xiàn)的讀問題。
1.2臟讀、不可重復讀,幻讀。
??臟讀(Dirty read):在一個事務中讀取到另一個事務沒有提交的數(shù)據(jù)。例如,當一個事務正在訪問數(shù)據(jù),并且對數(shù)據(jù)進行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時,另外一個事務也訪問這個數(shù)據(jù),然后使用了這個數(shù)據(jù)。
??不可重復讀(NonRepeatable Read):既不能讀到相同的數(shù)據(jù)內(nèi)容。是指在一個事務內(nèi),多次讀同一數(shù)據(jù),在這個事務還沒有結束時,另外一個事務也訪問該同一數(shù)據(jù)并且修改,那么,在第一個事務中的兩次讀數(shù)據(jù)之間,由于第二個事務的修改,第一個事務兩次讀到的的數(shù)據(jù)可能是不一樣的。
??幻讀(Phantom Read):在一個事務中,兩次查詢的結果不一致(針對的insert操作) 。是指當事務不是獨立執(zhí)行時發(fā)生的一種現(xiàn)象,例如第一個事務對一個表中的數(shù)據(jù)進行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時,第二個事務也修改這個表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后操作第一個事務的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣。
??例如,一個編輯人員更改作者提交的文檔,但當生產(chǎn)部門將其更改內(nèi)容合并到該文檔的主復本時,發(fā)現(xiàn)作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產(chǎn)部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。
二、數(shù)據(jù)庫事務隔離級別
??數(shù)據(jù)庫事務的隔離級別有4個,由低到高依次為Read uncommitted(讀未提交)、Read committed(讀提交) 、Repeatable read(可重復讀)、Serializable(序列化),這四個級別可以逐個解決臟讀 、不可重復讀 、幻讀這幾類問題。
2.1 Read uncommitted(讀未提交)
??公司發(fā)工資了,領導把5000元打到singo的賬號上,但是該事務并未提交,而singo正好去查看賬戶,發(fā)現(xiàn)工資到賬5000元整,非常高興。可是不幸的是,領導發(fā)現(xiàn)發(fā)給singo的工資金應該是2000元,于是迅速回滾了事務(將5000元回滾),修改金額后(修改為2000元),將事務提交,最后singo實際的工資只有 2000元,singo空歡喜一場。
??出現(xiàn)上述情況,即我們所說的臟讀 ,兩個并發(fā)的事務,“事務A:領導給singo發(fā)工資”,“事務B:singo查詢工資賬戶”,事務B讀取了事務A尚未提交的數(shù)據(jù)。
??當隔離級別設置為Read uncommitted(讀未提交)時,就可能出現(xiàn)臟讀,如果我們此時將隔離級別提升為Read committed(讀已提交),便可避免臟讀。
2.2 Read committed(讀已提交)
??singo拿著工資卡去消費,系統(tǒng)讀取到卡里確實有2000元,而此時她的老婆也正好在網(wǎng)上轉賬,把singo工資卡的2000元轉到另一賬戶,并在 singo之前提交了事務,當singo扣款時,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,到底是啥情況呢?
??出現(xiàn)上述情況,即我們所說的不可重復讀 ,兩個并發(fā)的事務,“事務A:singo消費”、“事務B:singo的老婆網(wǎng)上轉賬”,事務A事先讀取了數(shù)據(jù),事務B緊接了更新了數(shù)據(jù),并提交了事務,而事務A再次讀取該數(shù)據(jù)時,數(shù)據(jù)已經(jīng)發(fā)生了改變。
??當隔離級別設置為Read committed(讀已提交)時,避免了臟讀,但是可能會造成不可重復讀(既不能讀到相同的數(shù)據(jù)內(nèi)容)。
??大多數(shù)數(shù)據(jù)庫的默認級別就是Read committed(讀已提交),比如Sql Server , Oracle,此時如果將隔離級別提升為Repeatable read(可重復讀),可以避免臟讀和不可重復讀的發(fā)生。
2.3 Repeatable read(可重復讀)
??當隔離級別設置為Repeatable read(可重復讀)時,可以避免不可重復讀。當singo拿著工資卡去消費時,一旦系統(tǒng)開始讀取工資卡信息(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉賬。
??(這里兩個博客舉得例子不一樣,請各位看官指明原因)或者說,有A、B兩個會話,分別開啟兩個事務,然后A向B轉了500元錢,A 提交事務,B再去查看,發(fā)現(xiàn)依舊是原錢數(shù),B只能結束當前事務,在開啟一個新事務,才能查詢到數(shù)據(jù)的變化,這樣便避免了不可重復讀。如果我們設置了Seriizable(序列化),就相當于鎖表,某一時間內(nèi)只允許一個事務訪問該表。
??雖然Repeatable read避免了不可重復讀,但還有可能出現(xiàn)幻讀 。
??比如singo的老婆工作在銀行部門,她時常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額 (select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞后在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction … ),并提交了事務,隨后singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發(fā)現(xiàn)消費總額為1080元,singo的老婆很詫異,以為出 現(xiàn)了幻覺,幻讀就這樣產(chǎn)生了。
??注:Mysql的默認隔離級別就是Repeatable read。
2.4 Serializable(序列化)
??Serializable(序列化)是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執(zhí)行,不僅可以避免臟讀、不可重復讀,還避免了幻讀。
三、總結
3.1 隔離級別與對應可能產(chǎn)生的問題表
隔離級別 | 臟讀(Dirty read) | 不可重復讀(NonRepeatable Read) | 幻讀(Phantom Read) |
---|
讀未提交 (Read uncommitted) | 可能 | 可能 | 可能 |
讀已提交 (Read committed) | 不可能 | 可能 | 可能 |
可重復讀 (Repeatable read) | 不可能 | 不可能 | 可能 |
序列化 (Serializable) | 不可能 | 不可能 | 不可能 |
以上就是如何理解數(shù)據(jù)庫事務隔離級別及臟讀、不可重復讀、幻讀的詳細內(nèi)容,更多請關注php中文網(wǎng)其它相關文章!
學習教程快速掌握從入門到精通的SQL知識。