資料庫系列:MySQL慢查詢分析和效能優化
資料庫系列:MySQL索引優化總結(綜合版)
資料庫系列:高並行下的資料欄位變更
資料庫系列:覆蓋索引和規避回表
資料庫系列:資料庫高可用及無失真擴容
資料庫系列:使用高區分度索引列提升效能
資料庫系列:字首索引和索引長度的取捨
資料庫系列:MySQL引擎MyISAM和InnoDB的比較
資料庫系列:InnoDB下實現高並行控制
資料庫系列:事務的4種隔離級別
上一篇,我們介紹了 SQL92標準中事務的四種隔離級別,並討論了每種隔離級別下 髒讀、不可重複讀、幻讀 問題是否可以解決:
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀未提交:Read Uncommitted | ✔ | ✔ | × |
讀已提交:Read Committed | × | ✔ | × |
可重複讀:Repeatable Read | × | × | ✔ |
序列化:Serializable | × | × | × |
在 讀已提交(Read Committed) 和 可重複讀(Repeatable Read)兩種隔離級別上,資料庫底層採用了快照讀(Snapshot Read)的模式來實現高並行機制。
那RC 和 RR這兩種的隔離級別上的快照讀(Snapshot Read)有什麼區別呢,咱們往下探索?
MySQL中InnoDB儲存引擎的快照讀(Snapshot Read)是一種讀取資料的方式,它可以在事務開始時建立一個資料快照,這個快照是一致性的,即讀取在事務開始時或特定時間點之前提交的資料。底層原理是MySQL使用多版本並行控制(MVCC)機制來實現快照讀。在MVCC中,每個事務讀取的資料都是根據事務開始時間點或快照時間點確定的。MySQL通過為每一行資料新增版本資訊(如建立版本、刪除版本等),來保留歷史資料的多個版本。通過一種不加鎖一致性讀(Consistent Nonlocking Read)的方式來實現高並行的能力。
事務執行順序如下:
時間序列 | 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 隔離級別
Read Committed 隔離級別
事務執行順序如下:
時間序列 | 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; |
首先,事務總能夠讀取到自己寫入(update /insert /delete)的行記錄。而其他事務的提交,則分情況。
RC模式,快照讀總是能讀到最新的行資料快照,當然,必須是已提交事務寫入的。
RR模式,某個事務首次read記錄的時間為T1,之後的操作不會讀取到T1時間之後已提交事務寫入的記錄,以保證連續相同的read讀到相同的結果集。
簡單點說: