Isolation Level
Dirty Read
Unrepeatable Read
Phantom Read
Read UNCOMMITTED
YES
YES
YES
READ COMMITTED
NO
YES
YES
READ REPEATABLE
NO
NO
YES
SERIALIZABLE
NO
NO
NO
4. 數據庫的默認隔離級別 除了MySQL默認采用RR隔離級別之外,其它幾大數據庫都是采用RC隔離級別。 但是他們的實現也是極其不一樣的。Oracle僅僅實現了RC 和 SERIALIZABLE隔離級別。默認采用RC隔離級別,解決了髒讀。但是允許不可重復讀和幻讀。其SERIALIZABLE則解決了髒讀、不可重復讀、幻讀。 MySQL的實現:MySQL默認采用RR隔離級別,SQL標准是要求RR解決不可重復讀的問題,但是因為MySQL采用了gap lock,所以實際上MySQL的RR隔離級別也解決了幻讀的問題。那麼MySQL的SERIALIZABLE是怎麼回事呢?其實MySQL的SERIALIZABLE采用了經典的實現方式,對讀和寫都加鎖。 5. MySQL 中RC和RR隔離級別的區別 MySQL數據庫中默認隔離級別為RR,但是實際情況是使用RC 和 RR隔離級別的都不少。好像淘寶、網易都是使用的 RC 隔離級別。那麼在MySQL中 RC 和 RR有什麼區別呢?我們該如何選擇呢?為什麼MySQL將RR作為默認的隔離級別呢? 5.1 RC 與 RR 在鎖方面的區別 1> 顯然 RR 支持 gap lock(next-key lock),而RC則沒有gap lock。因為MySQL的RR需要gap lock來解決幻讀問題。而RC隔離級別則是允許存在不可重復讀和幻讀的。所以RC的並發一般要好於RR; 2> RC 隔離級別,通過 where 條件過濾之後,不符合條件的記錄上的行鎖,會釋放掉(雖然這裡破壞了“兩階段加鎖原則”);但是RR隔離級別,即使不符合where條件的記錄,也不會是否行鎖和gap lock;所以從鎖方面來看,RC的並發應該要好於RR; 5.2 RC 與 RR 在復制方面的區別 1> RC 隔離級別不支持 statement 格式的bin log,因為該格式的復制,會導致主從數據的不一致;只能使用 mixed 或者 row 格式的bin log; 這也是為什麼MySQL默認使用RR隔離級別的原因。復制時,我們最好使用:binlog_format=row 2> MySQL5.6 的早期版本,RC隔離級別是可以設置成使用statement格式的bin log,後期版本則會直接報錯; 5.3 RC 與 RR 在一致性讀方面的區別 簡單而且,RC隔離級別時,事務中的每一條select語句會讀取到他自己執行時已經提交了的記錄,也就是每一條select都有自己的一致性讀ReadView; 而RR隔離級別時,事務中的一致性讀的ReadView是以第一條select語句的運行時,作為本事務的一致性讀snapshot的建立時間點的。只能讀取該時間點之前已經提交的數據。 具體可以參加:MySQL 一致性讀 深入研究 5.4 RC 支持半一致性讀,RR不支持 RC隔離級別下的update語句,使用的是半一致性讀(semi consistent);而RR隔離級別的update語句使用的是當前讀;當前讀會發生鎖的阻塞。 1> 半一致性讀: A type of read operation used for UPDATE statements, that is a combination of read committed and consistent read. When an UPDATE statement examines a row that is already locked, InnoDB returns the latest committed version to MySQL so that MySQL can determine whether the row matches the WHERE condition of the UPDATE. If the row matches (must be updated), MySQL reads the row again, and this time InnoDB either locks it or waits for a lock on it. This type of read operation can only happen when the transaction has the read committed isolation level, or when the innodb_locks_unsafe_for_binlog option is enabled. 簡單來說,semi-consistent read是read committed與consistent read兩者的結合。一個update語句,如果讀到一行已經加鎖的記錄,此時InnoDB返回記錄最近提交的版本,由MySQL上層判斷此版本是否滿足 update的where條件。若滿足(需要更新),則MySQL會重新發起一次讀操作,此時會讀取行的最新版本(並加鎖)。semi-consistent read只會發生在read committed隔離級別下,或者是參數innodb_locks_unsafe_for_binlog被設置為true(該參數即將被廢棄)。 對比RR隔離級別,update語句會使用當前讀,如果一行被鎖定了,那麼此時會被阻塞,發生鎖等待。而不會讀取最新的提交版本,然後來判斷是否符合where條件。 半一致性讀的優點: 減少了update語句時行鎖的沖突;對於不滿足update更新條件的記錄,可以提前放鎖,減少並發沖突的概率。 Oracle中的update好像有“重啟動”的概念。