關於臟讀、幻象讀、不可重復讀的理解


一般大家都對事務的四種隔離模式比較熟悉,從松到嚴依次是:

- 讀取未提交(Read uncommitted):處於此模式下可能會出現臟讀、幻象讀、不可重復讀
- 讀取已提交(Read committed):處於此模式下可能會出現幻象讀、不可重復讀
- 可重復讀(Repeatable read):處於此模式下可能會出現幻象讀
- 串行(Serialize):不會出現幻象讀
 
那么臟讀、幻象行、不可重復讀是什么意思呢?
- 臟讀:其它的事務(執行單個 select 語句也算一個事務)可以讀取到某個事務更新(包括插入和刪除)了但未提交的數據。臟讀是應用中應該避免的,因為讀取的是不可靠的數據(我覺得把這個叫做幻象行更形象,實際卻不是)。一般數據庫不會設定為這個模式,但有時候也會用到。臟讀的好處是讀取時不會對表或記錄加鎖,可以繞開寫隊列的排隊,避免了等待。如在一個更新特別頻繁的表中要選擇表中所有的數據,就可以顯示指定隔離級別:
select .... at isolation 0
 
- 不可重復讀:這是描述在同一個事務中兩條一模一樣的 select 語句的執行結果的比較。如果前后執行的結果一樣,則是可重復讀;如果前后的結果可以不一樣,則是不可重復讀。這個特性從字面上也能看出來。
     不可重復讀的模式下首先不會出現臟讀,即讀取的都是已提交的數據。在一個事務中,讀取操作是不會加排他鎖的,當下一條一模一樣的 select 語句的執行時,命中的數據集可能已經被其它事務修改了,這時候,還能讀到相同的內容嗎?
     因此,要達到可重復讀的效果,數據庫需要做更多的事情,比如,對讀取的數據行加共享鎖,並保持到事務結束,以禁止其它事務修改它。這樣會降低數據庫的性能。而隔離級別的串行則比可重復讀更嚴格。一般數據庫的的隔離級別只設置到讀取已提交。這是兼顧了可靠性和性能的結果。
     上面還只提到了對命中的數據行加鎖,以防止其它事務修改它。但沒有提到,如果其它事務增加了符合條件的數據行怎么辦?有些數據庫對這種情況新定義了兩個級別:讀取穩定性和游標穩定性。前者不限制新增符合條件的數據行,而后者則阻止新增這樣的數據行。
 
- 幻象讀:是指兩次執行同一條 select 語句會出現不同的結果,第二次讀會增加一數據行,並沒有說這兩次執行是在同一個事務中。一般情況下,幻象讀應該正是我們所需要的。但有時候卻不是,如果打開的游標,在對游標進行操作時,並不希望新增的記錄加到游標命中的數據集中來。隔離級別為 游標穩定性 的,可以阻止幻象讀。
 


免責聲明!

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



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