前置知識
涉及到的幾個概念:隱藏欄位,undo log,readview
- (每個表中的)隱藏欄位:最后修改記錄的事務id,回滾指標
- undo log :在插入/更新資料的時候記錄回滾日志
- 當前讀:讀取的是記錄的最新版本,在執行的時候會加鎖,防止其他并發事務修改該記錄
select ... for update、update、insert、delete(排他鎖)都是一種當前讀 - 快照讀:讀取的可能是記錄的可見版本,可能是歷史記錄
對MVCC理解:
實作了事務隔離
每次開啟事務都會創建一個 read view ,以及回滾日志 undo log,從而會形成一潭訓滾鏈
關閉事務那么 read view 也會被關閉

回滾日志何時被清除?
如果 read-view A 被關閉了,且 '將2改成1' 這個回滾日志之前沒有 read-view 了,那么此回滾日志就可以被洗掉
分析利用MVCC特性讀取同一個記錄的不同版本

對于同一個記錄,如果對它開啟了多次事務,就會產生如圖中的多個快照讀 A,B,C,
假設事務A,B,C分別對應于上述快照讀,由圖可知當前值為4,如果事務 A 需要讀取該記錄值,那么需要由當前值 依次回滾 從而得到 1 這個值,
分析事務是否是隔離的
事務的隔離,指的就是多個事務的執行不會互相影響,具體點說,在 RR 隔離級別下,事務 A 在開啟后,多次讀取同一個記錄,讀取到的值始終是一致的,
從這個引出了一致性讀 (read-view) 這個概念,能夠保證事務 A 上述運行效果,依靠的是 MVCC (多版本并發控制) 這個概念,MVCC 通過 read-view,row_trx_id,回滾日志,回滾鏈等保證了前后讀取的一致性,這是對于一個事務中只有查詢操作而言的,
在事務 A 開啟后,其實對整個庫進行了一次快照,但是這個快照并不是真正的整個資料庫資料,這太龐大了,而是由 活躍事務陣列 來保證對全庫的快照,

活躍事務是指當前未提交的所有事務,通過這么一個活躍陣列,就達到了開啟事務后對全庫資料進行快照的效果,
從這個角度來看,事務是隔離的,因為這是站在只有查詢陳述句的視角,
而從下面這個視角來看,事務是不隔離的,因為有當前讀這個概念,

有上述兩個事務,初始資料 (id,k):(1,1),開啟事務 B
事務 C 更新后變成(1,2)
此時事務 B 才執行更新,而更新操作需要讀取此記錄的 當前值,也就是事務 B 讀取到了 (1,2),然后做更新;而后再次查詢,會發現(1,3)這種情況,
這樣看事務好像是非隔離的,因為事務 B 是先于事務 C 開啟的,它理應讀到 (1,1) 這樣的資料然后去做修改,
但是 MySQL 要保證不能丟失事務 C 的修改,且它已經提交了,所以可以得知:對于更新操作,是先讀后寫的,而且這個讀是當前讀(即該記錄的最新版本值),并且要獲取行寫鎖 ( X ),
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/542749.html
標籤:其他
