數據庫的臟讀、不可重復讀、幻讀都和事務的隔離性有關,所以先了解一下事務的4大特性。
事務的4大特性(ACID)
- 原子性(Atomicity):事務是數據庫的邏輯工作單位,它對數據庫的修改要么全部執行,要么全部不執行。
- 一致性(Consistemcy):事務前后,數據庫的狀態都滿足所有的完整性約束。
- 隔離性(Isolation): 並發執行的N個事務是隔離的,一個不影響一個,一個事務在沒有commit之前,被修改的數據不可能被其他事務看到(通過設置數據庫的隔離級別)。
- 持久性(Durability): 持久性意味着當系統或介質發生故障時,確保已提交事務的更新不能丟失。持久性主要在於DBMS的恢復性能。
事務的隔離級別從低到高
- Read Uncommitted:最低的隔離級別,什么都不需要做,一個事務可以讀到另一個事務未提交的結果。所有的並發事務問題都會發生。
- Read Committed:只有在事務提交后,其更新結果才會被其他事務看見。解決臟讀問題。
- Repeated Read:在一個事務中,對於同一份數據的讀取結果總是相同的,無論是否有其他事務對這份數據進行操作,以及這個事務是否提交。可以解決臟讀、不可重復讀。
- Serialization:事務串行化執行,隔離級別最高,犧牲了系統的並發性。可以解決並發事務的所有問題。通常,在工程實踐中,為了性能的考慮會對隔離性進行折中。
臟讀
臟讀又稱無效數據讀出。一個事務讀取另外一個事務還沒有提交的數據叫臟讀。
例如:事務T1修改了一行數據,但是還沒有提交,這時候事務T2讀取了被事務T1修改后的數據,之后事務T1因為某種原因Rollback了,那么事務T2讀取的數據就是臟的。
解決辦法:把數據庫的事務隔離級別調整到READ_COMMITTED
不可重復讀
不可重復讀是指在同一個事務內,兩個相同的查詢返回了不同的結果。
例如:事務T1讀取某一數據,事務T2讀取並修改了該數據,T1為了對讀取值進行檢驗而再次讀取該數據,便得到了不同的結果。
解決辦法:把數據庫的事務隔離級別調整到REPEATABLE_READ
幻讀
幻讀是指當事務不是獨立執行時發生的一種現象。
例如:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣。這就叫幻讀。
解決辦法:把數據庫的事務隔離級別調整到SERIALIZABLE_READ
注意:
臟讀、不可重復讀、幻讀的級別高低是:臟讀 < 不可重復讀 < 幻讀。所以,設置了最高級別的SERIALIZABLE_READ就不用在設置REPEATABLE_READ和READ_COMMITTED了
不可重復讀重點是修改;幻讀重點是新增、刪除