快照讀是基於 MVCC 和 undo log 來實現的,適用於簡單 select 語句。sql
讀已提交:一個事務內操做一條數據,能夠查詢到另外一個已提交事務操做同一條數據的最新值。(Oracle 默認隔離級別)併發
可重複讀:每一個事務只關注本身事務開始查詢到的數據值,不管事務查詢同一條數據多少次,該數據改了多少次,都只查詢到事務開始以前的數據值。(MySQL 默認隔離級別)spa
而所謂 MVCC 併發版本控制,是靠 readView (事務視圖) 來實現的。多個 readView 組成 undo log(回滾日誌)。版本控制
每個 sql 查詢某條數據時,都是查詢最新 readView 的該條數據的值。日誌
ReadView:(查詢同一條數據,由於 readView 也是針對同一條數據生成的視圖)事務
讀已提交:是事務中的每一個 sql 語句生成一個 readView。那就是一個事務內多條 sql 語句,會生成多個 readView。而每條 sql 執行時,都是查詢最新 readView 的值。date
假如事務 A 有2個查詢 sql 語句,在第一個查詢 sql 生成一個 readView(事務視圖 id = n),事務 B 對該數據作了操做,那麼就會生成新的 readView(事務視圖 id = n + 1),第二個查詢 sql 語句獲取該條數據時,就會去 readView(事務視圖 id = n + 1)查詢數據。select
可重複讀:是在事務開始的時候生成一個 readView。因此一個事務內的多條查詢 sql ,查詢同一條數據時,讀取到的 readView 都是同一個,那麼查詢某條數據的值,也是同一個值。數據
例如事務A開始查詢主鍵 id = 1 的行數據的列 age = 10,無論其餘事務是否對該 age 作改變,當前事務的多條查詢 sql 語句,查詢 age 的值一直都是 age = 10。查詢
當前讀是基於 臨鍵鎖(行鎖 + 間歇鎖)來實現的,適用於 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釋放鎖。