mysql原理(十) 當前讀與快照讀

首先我們做一個模擬,執行以下的sql,其中有如下圖數據:

時間 會話1 會話2 會話3
1 begin;
select * from t_student where id = 2
2 update t_student set age = age + 1 where id =2;;
3 begin;
update t_student set age = age + 1 where id =2;;
4 select * from t_student where id =2;
COMMIT
5 select * from t_student where id = 2;
6 COMMIT;
select * from t_student where id = 2;

我把執行結果按照表格如下展示:

時間 會話1 會話2 會話3
1 15
2
3
4 17
5 15
6 17

分析:
在會話1當中,只有當會話1的事務提交後,才能查到最終會話2更改的數據。
在會話2當中,開啓事務後更新數據,之後查詢發現數據變成了17。

針對上面的現象我們進行個原理分析:
實際上產生上述顯現是因爲InnoDB採用的MVCC(多版本併發控制),其中針對每條數據會有它自己的事務id,以及一個最大事務id。針對事務中數據每次修改,會產生不同的版本。

1)假設開始id = 2的數據,其事務txid = 1000;
2)當會話1開始,此時txid變成了1001,而會話2開啓,txid又變成了1002,同理會話3會變成1003,此時都生成了不同版本的快照。
3)會話1在事務當中去讀取時候,採用了快照讀的方式,即拿到一個1001的事務id,此時只會讀取小於等於自己版本的數據,所以在事務中最終只能拿到值爲17的數據。
4)會話2在更新數據的時候,採用的當前讀的方式,即對數據增加X鎖,獲取最新的事務id,讀取最新的版本數據。所以在更新之前,就讀取到了age的年齡是16,之後在進行+1,得到17.

總結一下:

快照讀解決了幻讀的問題,即多次讀取數據不一致的問題。

update、insert、delete都會執行當前讀,防止併發更新數據導致數據錯誤,此過程或添加X鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章