一、事務的四大特性
-
原子性(Atomicity)
事務包含的所有資料庫操作要麼全部成功,要不全部失敗回滾。 -
一致性(Consistency)
一致性是指事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態。一致性規定事務提交前後只存在兩個狀態,提交前的狀態和提交後的狀態,絕對不會出現中間的狀態。最典型的例子就是銀行轉賬,A和B之間互相轉賬,賬面加起來總和5000元,無論A和B之間怎麼轉,轉幾次,成功與否,事務結束後A和B賬面總和還是5000元。 -
隔離性(Isolation)
隔離性是當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作所干擾,多個併發事務之間要相互隔離。即要達到這麼一種效果:對於任意兩個併發的事務T1和T2,在事務T1看來,T2要麼在T1開始之前就已經結束,要麼在T1結束之後才開始,這樣每個事務都感覺不到有其他事務在併發地執行。 -
永續性(Durability)
永續性是指一個事務一旦被提交了,那麼對資料庫中的資料的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作。
二、事務併發時存在的問題
-
髒讀(Dirty Read)
髒資料所指的就是未提交的資料,而髒讀是指在一個事務處理過程裡讀取了另一個未提交的事務中的資料。比如,一個事務正在對一條記錄做修改,在這個事務完成並提交之前,這條資料是處於待定狀態的(可能提交也可能回滾),這時,第二個事務來讀取這條沒有提交的資料,並據此做進一步的處理,就會產生未提交的資料依賴關係。這種現象被稱為髒讀。 -
不可重複讀(Non-repeatable Read)
一個事務先後讀取同一條記錄,而事務在兩次讀取之間該資料被其它事務所修改,則兩次讀取的資料不同,我們稱之為不可重複讀。例如事務T1在讀取某一資料,而事務T2立馬修改了這個資料並且提交事務給資料庫,事務T1再次讀取該資料就得到了不同的結果,傳送了不可重複讀。
不可重複讀和髒讀的區別:髒讀是某一事務讀取了另一個事務未提交的髒資料,而不可重複讀則是在同一事務內讀取了前一事務提交的資料,即前一次讀到的資料是另一個事務提交前,後一次讀到的資料是提交後的。
- 幻讀(Phantom Read)
一個事務按相同的查詢條件重新讀取以前檢索過的資料,卻發現其他事務插入了滿足其查詢條件的新資料,這種現象就稱為幻讀。幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,比如這種修改涉及到表中的“全部資料行”。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入“一行新資料”。那麼,以後就會發生操作第一個事務的使用者發現表中還存在沒有修改的資料行,就好象發生了幻覺一樣。
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。
在實際開發和使用中,其實幻讀問題是可以接受也符合使用者的心理預期,比如在淘寶雙十一搶東西,點選“購買”,成功進入“下單頁面”,結果到“付款頁面”卻提示已經被搶完,這是可以接受的。
三、四個隔離級別
-
讀未提交(Read uncommitted)
所有事務都可以看到其他未提交事務的執行結果。本隔離級別是最低的隔離級別,雖然擁有超高的併發處理能力及很低的系統開銷,但很少用於實際應用。因為採用這種隔離級別只能防止更新丟失問題(這個問題現代關係型資料庫已經不會發生),不能解決髒讀,不可重複讀及幻讀問題。 -
讀已提交(Read committed)
這是大多數資料庫系統的預設隔離級別(但不是MySQL預設的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別可以防止髒讀問題,但會出現不可重複讀及幻讀問題。 -
可重複讀(Repeatable read)
這是MySQL的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。這種隔離級別可以防止除幻讀外的其他問題。 -
序列化(Serializable )
這是最高的隔離級別,它透過強制事務排序,使之不可能相互衝突,從而解決幻讀、第二類更新丟失問題。在這個級別,可以解決上面提到的所有併發問題,但可能導致大量的超時現象和鎖競爭,通常資料庫不會用這個隔離級別,我們需要其他的機制來解決這些問題:樂觀鎖和悲觀鎖。
學習地址:https://blog.csdn.net/weixin_43146572/article/details/117413762