數據庫的臟讀、不可重復讀、幻讀以及不可重復讀和幻讀的區別


介紹

數據庫的臟讀、不可重復讀、幻讀都和事務的隔離性有關。所以先了解一下事務的4大特性。 

事務的4大特性(ACID):

原子性(Atomicity):事務是數據庫的邏輯工作單位,它對數據庫的修改要么全部執行,要么全部不執行。 
一致性(Consistemcy):事務前后,數據庫的狀態都滿足所有的完整性約束。 
隔離性(Isolation):並發執行的N個事務是隔離的,一個不影響一個,一個事務在沒有commit之前,被修改的數據不可能被其他事務看到(通過設置數據庫的隔離級別)。 
持久性(Durability):持久性意味着當系統或介質發生故障時,確保已提交事務的更新不能丟失。持久性主要在於DBMS的恢復性能。

臟讀:

臟讀又稱無效數據讀出。一個事務讀取另外一個事務還沒有提交的數據叫臟讀。

例如:事務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了


 區別

不可重復讀

不可重復讀的重點是修改 
同樣的條件, 你讀取過的數據, 再次讀取出來發現值不一樣了

例子:在事務1中,Mary 讀取了自己的工資為1000,操作並沒有完成

--在postresql中的例子,可能和其他的數據庫略有區別 begin transaction; select salary from employee where id = MaryID;

在事務2中,這時財務人員修改了Mary的工資為2000,並提交了事務.

begin transaction; update employee set salary = 2000 where id = MaryID; commit;

在事務1中,Mary 再次讀取自己的工資時,工資變為了2000

select salary from employee where id = MaryID;

在一個事務中前后兩次讀取的結果並不致,導致了不可重復讀。

幻讀

幻讀的重點在於新增或者刪除 
同樣的條件, 第1次和第2次讀出來的記錄數不一樣

例子:目前工資為1000的員工有10人。 
事務1,讀取所有工資為1000的員工。

begin transaction; select * from employee where salary = 1000; -- 共讀取10條記錄 

這時另一個事務向employee表插入了一條員工記錄,工資也為1000

begin transaction; insert into employee(,salary,) values(,1000,); commit;

事務1再次讀取所有工資為1000的員工

--事務1 select * from employee where salary = 1000; --共讀取到了11條記錄

這就產生了幻像讀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM