1. 程式人生 > 實用技巧 >MySQL事務——隔離性

MySQL事務——隔離性

目錄

髒讀、幻讀和不可重複讀

髒讀(讀取未提交資料)

A事務讀取B事務尚未提交的資料,此時如果B事務發生錯誤並執行回滾操作,那麼A事務讀取到的資料就是髒資料。就好像原本的資料比較乾淨、純粹,此時由於B事務更改了它,這個資料變得不再純粹。這個時候A事務立即讀取了這個髒資料,但事務B良心發現,又用回滾把資料恢復成原來乾淨、純粹的樣子,而事務A卻什麼都不知道,最終結果就是事務A讀取了此次的髒資料,稱為髒讀。

這種情況常發生於轉賬與取款操作中
在這裡插入圖片描述

不可重複讀(前後多次讀取,資料內容不一致)

事務A在執行讀取操作,由整個事務A比較大,前後讀取同一條資料需要經歷很長的時間 。而在事務A第一次讀取資料,比如此時讀取了小明的年齡為20歲,事務B執行更改操作,將小明的年齡更改為30歲,此時事務A第二次讀取到小明的年齡時,發現其年齡是30歲,和之前的資料不一樣了,也就是資料不重複了,系統不可以讀取到重複的資料,成為不可重複讀。
在這裡插入圖片描述

幻讀(前後多次讀取,資料總量不一致)

事務A在執行讀取操作,需要兩次統計資料的總量,前一次查詢資料總量後,此時事務B執行了新增資料的操作並提交後,這個時候事務A讀取的資料總量和之前統計的不一樣,就像產生了幻覺一樣,平白無故的多了幾條資料,成為幻讀。

在這裡插入圖片描述
參考部落格連結: 【資料庫】快速理解髒讀、不可重複讀、幻讀

事務隔離級別

有四種隔離級別,分別是讀未提交(Read uncommitted),讀已提交(Read committed),可重複讀(Repeatable read),可序列化(Serializable),用來解決資料庫操作中產生的各種問題。

事務的四大特徵ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一 致性、隔離性、永續性)

讀未提交(Read uncommitted)

在這種隔離級別下,所有事務能夠讀取其他事務未提交的資料。讀取其他事務未提交的資料,會造成髒讀。因此在該種隔離級別下,不能解決髒讀、不可重複讀和幻讀。

讀未提交可能會產生髒讀的現象,那麼怎麼解決髒讀呢?那就是使用讀已提交。

讀已提交(Read committed)

在這種隔離級別下,所有事務只能讀取其他事務已經提交的內容。能夠徹底解決髒讀的現象。但在這種隔離級別下,會出現一個事務的前後多次的查詢中卻返回了不同內容的資料的現象,也就是出現了不可重複讀。

注意: 這是大多數資料庫系統預設的隔離級別,例如Oracle和SQL Server,但mysql不是。

已提交可能會產生不可重複讀的現象,我們可以使用可重複讀。

可重複讀(Repeatable read)

在這種隔離級別下,所有事務前後多次的讀取到的資料內容是不變的。也就是某個事務在執行的過程中,不允許其他事務進行update操作,但允許其他事務進行add操作,造成某個事務前後多次讀取到的資料總量不一致的現象,從而產生幻讀。

注意: 這才是mysql的預設事務隔離級別。產生的幻讀該如何解決呢?使用間隙鎖的方式就已經解決了幻讀的問題。預留【加鎖處理過程】

可重複讀依然會產生幻讀的現象,此時我們可以使用序列化來解決。

可序列化(Serializable)

在這種隔離級別下,所有的事務順序執行,所以他們之間不存在衝突,從而能有效地解決髒讀、不可重複讀和幻讀的現象。但是安全和效率不能兼得,這樣事務隔離級別,會導致大量的操作超時和鎖競爭,從而大大降低資料庫的效能,一般不使用這樣事務隔離級別。

總結

在這裡插入圖片描述
參考部落格連結: 【資料庫】事務隔離級別