您好,登錄后才能下訂單哦!
mysql數據庫事務隔離級別及臟讀、不可重復讀、幻讀是什么?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!
1.1ACID原則。
??ACID原則是數據庫事務正常執行的四個基本要素,分別指原子性、一致性、獨立性及持久性。
??事務的原子性(Atomicity)是指一個事務要么全部執行,要么不執行,也就是說一個事務不可能只執行了一半就停止了,比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢。不可能劃了卡,而錢卻沒出來,這兩步必須同時完成.要么就不完成。
??事務的一致性(Consistency)是指事務的運行并不改變數據庫中數據的一致性。例如,完整性約束了a+b=10,一個事務改變了a,那么b也應該隨之改變。或者說,A給B轉賬300元錢,那么A的賬戶就必須是減少300元錢,B的賬戶就必須是增加300元錢,不能說是增加或減少了如200元錢等,這里符合事務的原子性,但是不符合事務的一致性。往實際業務中沒有這么簡單,往是類似買東西扣庫存這類的邏輯,主表里有庫存,庫存表里有庫存,SKU表里還有,然后就因為設計缺陷,就算加了事務還是出現了超賣、SKU庫存對不上總庫存的問題,這個就是一致性不滿足的了。
??獨立性(Isolation):事務的獨立性也有稱作隔離性,是指兩個以上的事務不會出現交錯執行的狀態,因為這樣可能會導致數據不一致。
??持久性(Durability):一旦事務提交或者回滾,這個狀態都要持久化到數據庫中,不考慮隔離性會出現的讀問題。
1.2臟讀、不可重復讀,幻讀。
??臟讀(Dirty read):在一個事務中讀取到另一個事務沒有提交的數據。例如,當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。
??不可重復讀(NonRepeatable Read):既不能讀到相同的數據內容。是指在一個事務內,多次讀同一數據,在這個事務還沒有結束時,另外一個事務也訪問該同一數據并且修改,那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改,第一個事務兩次讀到的的數據可能是不一樣的。
??幻讀(Phantom Read):在一個事務中,兩次查詢的結果不一致(針對的insert操作) 。是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。
??例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合并到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。
??數據庫事務的隔離級別有4個,由低到高依次為Read uncommitted(讀未提交)、Read committed(讀提交) 、Repeatable read(可重復讀)、Serializable(序列化),這四個級別可以逐個解決臟讀 、不可重復讀 、幻讀這幾類問題。
2.1 Read uncommitted(讀未提交)
??公司發工資了,領導把5000元打到singo的賬號上,但是該事務并未提交,而singo正好去查看賬戶,發現工資到賬5000元整,非常高興。可是不幸的是,領導發現發給singo的工資金應該是2000元,于是迅速回滾了事務(將5000元回滾),修改金額后(修改為2000元),將事務提交,最后singo實際的工資只有 2000元,singo空歡喜一場。
??出現上述情況,即我們所說的臟讀 ,兩個并發的事務,“事務A:領導給singo發工資”,“事務B:singo查詢工資賬戶”,事務B讀取了事務A尚未提交的數據。
??當隔離級別設置為Read uncommitted(讀未提交)時,就可能出現臟讀,如果我們此時將隔離級別提升為Read committed(讀已提交),便可避免臟讀。
2.2 Read committed(讀已提交)
??singo拿著工資卡去消費,系統讀取到卡里確實有2000元,而此時她的老婆也正好在網上轉賬,把singo工資卡的2000元轉到另一賬戶,并在 singo之前提交了事務,當singo扣款時,系統檢查到singo的工資卡已經沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,到底是啥情況呢?
??出現上述情況,即我們所說的不可重復讀 ,兩個并發的事務,“事務A:singo消費”、“事務B:singo的老婆網上轉賬”,事務A事先讀取了數據,事務B緊接了更新了數據,并提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。
??當隔離級別設置為Read committed(讀已提交)時,避免了臟讀,但是可能會造成不可重復讀(既不能讀到相同的數據內容)。
??大多數數據庫的默認級別就是Read committed(讀已提交),比如Sql Server , Oracle,此時如果將隔離級別提升為Repeatable read(可重復讀),可以避免臟讀和不可重復讀的發生。
2.3 Repeatable read(可重復讀)
??當隔離級別設置為Repeatable read(可重復讀)時,可以避免不可重復讀。當singo拿著工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉賬。
??(這里兩個博客舉得例子不一樣,請各位看官指明原因)或者說,有A、B兩個會話,分別開啟兩個事務,然后A向B轉了500元錢,A 提交事務,B再去查看,發現依舊是原錢數,B只能結束當前事務,在開啟一個新事務,才能查詢到數據的變化,這樣便避免了不可重復讀。如果我們設置了Seriizable(序列化),就相當于鎖表,某一時間內只允許一個事務訪問該表。
??雖然Repeatable read避免了不可重復讀,但還有可能出現幻讀 。
??比如singo的老婆工作在銀行部門,她時常通過銀行內部系統查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額 (select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞后在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction … ),并提交了事務,隨后singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發現消費總額為1080元,singo的老婆很詫異,以為出 現了幻覺,幻讀就這樣產生了。
??注:Mysql的默認隔離級別就是Repeatable read。
2.4 Serializable(序列化)
??Serializable(序列化)是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免臟讀、不可重復讀,還避免了幻讀。
3.1 隔離級別與對應可能產生的問題表
隔離級別 | 臟讀(Dirty read) | 不可重復讀(NonRepeatable Read) | 幻讀(Phantom Read) |
---|---|---|---|
讀未提交 (Read uncommitted) | 可能 | 可能 | 可能 |
讀已提交 (Read committed) | 不可能 | 可能 | 可能 |
可重復讀 (Repeatable read) | 不可能 | 不可能 | 可能 |
序列化 (Serializable) | 不可能 | 不可能 | 不可能 |
感謝各位的閱讀!看完上述內容,你們對mysql數據庫事務隔離級別及臟讀、不可重復讀、幻讀是什么大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。