數據庫系列:RR和RC下,快照讀的區別


數據庫系列:MySQL慢查詢分析和性能優化
數據庫系列:MySQL索引優化總結(綜合版)
數據庫系列:高並發下的數據字段變更
數據庫系列:覆蓋索引和規避回表
數據庫系列:數據庫高可用及無損擴容
數據庫系列:使用高區分度索引列提升性能
數據庫系列:前綴索引和索引長度的取舍
數據庫系列:MySQL引擎MyISAM和InnoDB的比較
數據庫系列:InnoDB下實現高並發控制
數據庫系列:事務的4種隔離級別

1 介紹

上一篇,我們介紹了 SQL92標准中事務的四種隔離級別,並討論了每種隔離級別下 臟讀、不可重復讀、幻讀 問題是否可以解決:

隔離級別 臟讀 不可重復讀 幻讀
讀未提交:Read Uncommitted ×
讀已提交:Read Committed × ×
可重復讀:Repeatable Read × ×
串行化:Serializable × × ×

在 讀已提交(Read Committed) 和 可重復讀(Repeatable Read)兩種隔離級別上,數據庫底層采用了快照讀(Snapshot Read)的模式來實現高並發機制。
那RC 和 RR這兩種的隔離級別上的快照讀(Snapshot Read)有什么區別呢,咱們往下探索?

2 RC 和 RR下快照讀的區別

2.1 啥是快照讀?

MySQL中InnoDB存儲引擎的快照讀(Snapshot Read)是一種讀取數據的方式,它可以在事務開始時創建一個數據快照,這個快照是一致性的,即讀取在事務開始時或特定時間點之前提交的數據。底層原理是MySQL使用多版本並發控制(MVCC)機制來實現快照讀。在MVCC中,每個事務讀取的數據都是根據事務開始時間點或快照時間點確定的。MySQL通過為每一行數據添加版本信息(如創建版本、刪除版本等),來保留歷史數據的多個版本。通過一種不加鎖一致性讀(Consistent Nonlocking Read)的方式來實現高並發的能力。

2.2 RU和Serializable為啥不采用快照讀?

  • Serializable是串行化執行,每個步驟都是順序的,一項事務執行完成才能執行另一項事務,所以沒有MVCC 多版本的必要。
  • RU是讀未提交,所有未完成的、未最終提交事務都可以被讀取到,所以任何有變化的數據都會被讀取到,即使是還沒有Commit,也沒有多版本的必要了。

2.3 讀已提交(Read Committed)

  • 事務隔離級別的一種,簡稱RC
  • 解決了“臟讀”問題,保證讀取到的所有都是已提交事務的,並最終落庫的
  • 可能存在“讀幻影行”問題,同一個事務中,前后連續的select可能讀到不同的結果集

2.4 可重復讀(Repeated Read)

  • 事務隔離級別的一種,簡稱RR
  • 它不僅解決“臟讀”問題,還解決了“讀幻影行”的問題,同一個事務里,前后連續的select讀到始終相同的結果集

2.5 不同隔離級別下快照讀的區別

2.5.1 案例解析1

事務執行順序如下:

時間序列 A事務 B事務
T1 開始事務
T2 開始事務
T3 查詢xx賬戶余額(假設默認有500元)
★SELECT balance FROM acount WHERE customer_id=123456;
T4 xx賬戶存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T5 查詢A賬戶余額
T6 提交事務
★commit;
T7 查詢A賬戶余額
  • Repeated Read 隔離級別

    • T3讀到的結果肯定是500,這是B事務的第一個read
    • T5讀到的結果也是500,因為A事務還沒有提交
    • T7讀到的結果還是500,因為A事務是在時間T5之后提交的,T7讀到和T5一樣的結果(重復讀)
  • Read Committed 隔離級別

    • T3讀到的結果肯定是500,這是B事務的第一個read
    • T5讀到的結果也是500,因為A事務還沒有提交
    • T7讀到的結果還是1500,因為A事務已經提交,T7讀到Commit后的結果(讀已提交)

2.5.2 案例解析2

事務執行順序如下:

時間序列 A事務 B事務
T1 開始事務(假設默認有500元)
T2 開始事務
T3 xx賬戶存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T4 提交事務
★commit;
T5 查詢A賬戶余額
★SELECT balance FROM acount WHERE customer_id=123456;
  • Repeated Read 隔離級別:唯一的一次讀是在A事務提交之后的讀,所以結果肯定是1500
  • Read Committed 隔離級別:讀取已提交之后的數據,所以毫無疑問依然是1500

2.6 區別總結

首先,事務總能夠讀取到自己寫入(update /insert /delete)的行記錄。而其他事務的提交,則分情況。
RC模式,快照讀總是能讀到最新的行數據快照,當然,必須是已提交事務寫入的。
RR模式,某個事務首次read記錄的時間為T1,之后的操作不會讀取到T1時間之后已提交事務寫入的記錄,以保證連續相同的read讀到相同的結果集。
簡單點說:

  • RR下,事務在第一個Read操作時,會建立Read View,並貫穿整個事務的過程,保證了可重復讀的效果。
  • RC下,事務在每次Read操作時,都會建立Read View,以保證獲取到的都是數據庫中最新的被Commit的值。


免責聲明!

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



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