髒讀、幻讀和不可重複讀
阿新 • • 發佈:2019-12-31
資料庫的四大事務特徵
在資料庫中,事務要滿足ACID:
Atomicity 原子性:
- 事務是一個原子性質的操作單元,事務裡面的對資料庫的操作要麼都執行,要麼都不執行。
- 例子:銀行轉賬時,假設過程是A賬號扣款,B賬號加款。這兩個步驟要麼都執行,要麼就都不執行。否則如果只執行了扣款語句,就提交了,此時如果突然斷電,A賬號已經發生了扣款,B賬號卻沒收到加款,在生活中就會引起糾紛。
Consistent 一致性:
- 一致性是指在事務開始之前和事務結束以後,資料庫的完整性約束沒有被破壞。這是說資料庫事務不能破壞關係資料的完整性以及業務邏輯上的一致性。
- 例子: 對銀行轉帳事務,不管事務成功還是失敗,應該保證事務結束後ACCOUNT表中A和B的存款總額為x元不變。
Isolation 隔離性:
- 資料庫允許多個併發事務同事對資料進行操作,隔離性保證各個事務相互獨立,事務處理時的中間狀態對其它事務是不可見的,以此防止出現資料不一致狀態。
- 例子: 在Windows中,如果多個程式對同一個檔案進行修改是不允許的,Windows通過這種方式來保證不同程式的隔離性。
Durable 永續性:
- 一個事務處理結束後,其對資料庫的修改就是永久性的,即使系統故障也不會丟失。
髒讀、幻讀和不可重複讀的概念
髒讀:
所謂髒讀是指一個事務中訪問到了另外一個事務未提交的資料,如下圖:
如果會話 2 更新 age 為 10,但是在 commit 之前,會話 1 希望得到 age,那麼會獲得的值就是更新前的值。或者如果會話 2 更新了值但是執行了 rollback,而會話 1 拿到的仍是 10。這就是髒讀。不可重複讀:
一個事務查詢同一條記錄2次,得到的結果不一致:
由於在讀取中間變更了資料,所以會話 1 事務查詢期間的得到的結果就不一樣了。
幻讀:
一個事務查詢2次,得到的記錄條數不一致:
幻讀是不可重複讀的一種特殊場景。
MySQL 資料隔離級別
MySQL 裡有四個隔離級別:
- Read uncommttied(可以讀取未提交資料)
- Read committed(可以讀取已提交資料)
- Repeatable read(可重複讀)
- Serializable(可序列化)。
不同事務隔離級別有不同的效果:
在 InnoDB 中,預設為 Repeatable 級別,InnoDB 中使用一種被稱為 next-key locking 的策略來避免幻讀(phantom)現象的產生。
隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。