《快照讀、當前讀和MVCC》


1、快照讀

  快照讀是基於 MVCC 和 undo log 來實現的,適用於簡單 select 語句。

  讀已提交:一個事務內操作一條數據,可以查詢到另一個已提交事務操作同一條數據的最新值。(Oracle 默認隔離級別)

  可重復讀:每個事務只關注自己事務開始查詢到的數據值,無論事務查詢同一條數據多少次,該數據改了多少次,都只查詢到事務開始之前的數據值。(MySQL 默認隔離級別)

  而所謂 MVCC 並發版本控制,是靠 readView (事務視圖) 來實現的。多個 readView 組成 undo log(回滾日志)。

  每一個 sql 查詢某條數據時,都是查詢最新 readView 的該條數據的值。

  ReadView:(查詢同一條數據,因為 readView 也是針對同一條數據生成的視圖)

  讀已提交:是事務中的每個 sql 語句生成一個 readView。那就是一個事務內多條 sql 語句,會生成多個 readView。而每條 sql 執行時,都是查詢最新 readView 的值。

  假如事務 A 有2個查詢 sql 語句,在第一個查詢 sql 生成一個 readView(事務視圖 id = n),事務 B 對該數據做了操作,那么就會生成新的 readView(事務視圖 id = n + 1),第二個查詢 sql 語句獲取該條數據時,就會去 readView(事務視圖 id = n + 1)查詢數據。

  可重復讀:是在事務開始的時候生成一個 readView。所以一個事務內的多條查詢 sql ,查詢同一條數據時,讀取到的 readView 都是同一個,那么查詢某條數據的值,也是同一個值。

  例如事務A開始查詢主鍵 id = 1 的行數據的列 age = 10,不管其他事務是否對該 age 做改變,當前事務的多條查詢 sql 語句,查詢 age 的值一直都是 age = 10。

2、當前讀

  當前讀是基於 臨鍵鎖(行鎖 + 間歇鎖)來實現的,適用於 insert,update,delete, select ... for update, select ... lock in share mode 語句,以及加鎖了的 select 語句。

  當前讀:

  更新數據時,都是先讀后寫,而這個讀,就是當前讀。讀取數據時,讀取該條數據的已經提交的最新的事務,生成的 readView。

  例如事務 A 有2個 sql 語句,事務開始時生成 readView(id = n),第一個 sql 操作一條數據時讀當前的 readView(id = n) 。此時開始事務B生成 readView(id = n + 1),並且對該條數據做了操作(非簡單 select 操作)。事務A的第2個 sql 語句當前讀該數據時,就會讀取該數據的最新事務視圖 readView (id =n + 1) 的值。

  而假如事務A的第二個 sql 語句操作數據時,事務B還未提交(非簡單 select 操作),那么該條數據此時被事務B的寫鎖鎖住。事務A的第二個 sql 語句操作數據(非簡單 select 操作),那么也要獲取該條數據的鎖。而此時鎖被事務B持有,事務A就會阻塞,等待事務B釋放鎖。

 


免責聲明!

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



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