事務隔離級別底層的鎖以及InnoDB的事務隔離級別實現

事務隔離級別底層的鎖以及InnoDB的事務隔離級別實現

在這裏插入圖片描述

事務隔離級別底層的鎖

未提交讀:不加鎖,因爲隔離級別太低,幾乎不用。

串行化:把所有的查詢語句默認加共享鎖,會個更新鎖和排它鎖進行互斥,從而使得事務有序進行。

先來說一下MVCC

多版本併發控制,MVCC 是一種併發控制的方法,一般在數據庫管理系統中,實現對數據庫的併發訪問;在編程語言中實現事務內存。各個存儲引擎對於MVCC的實現各不相同。這些不同中的一些包括樂觀和悲觀併發控制只用於事務隔離級別中的讀已提交和可重複讀

MVCC會保存某個時間點上的數據快照。這意味着事務可以看到一個一致的數據視圖,不管他們需要跑多久。這同時也意味着不同的事務在同一個時間點看到的同一個表的數據可能是不同的。

可將MVCC看成行級別鎖的一種妥協,它在許多情況下避免了使用鎖,同時可以提供更小的開銷。根據實現的不同,它可以允許非阻塞式讀,在寫操作進行時只鎖定必要的記錄。

InnoDB事務隔離級別的實現

InnoDB通過爲每一行記錄添加兩個額外的隱藏的值來實現MVCC,這兩個值一個記錄這行數據何時被創建,另外一個記錄這行數據何時過期(或者被刪除)。但是InnoDB並不存儲這些事件發生時的實際時間,相反它只存儲這些事件發生時的系統版本號。這是一個隨着事務的創建而不斷增長的數字。每個事務在事務開始時會記錄它自己的系統版本號。每個查詢必須去檢查每行數據的版本號與事務的版本號是否相同。

看下面這張照片
在這裏插入圖片描述
先區分一下快照讀和當前讀

快照讀:就是第一次讀取的時候將數據進行了備份,在以後的讀取過程中讀取的都是備份中的數據。
當前讀:就是每次讀取的時候,都是獲得的是最新的數據。

不加鎖的查詢使用的是快照讀,加鎖的查詢就是當前讀。

記錄鎖(普通的行鎖)

記錄鎖(record lock):唯一性索引,等值查詢,精準匹配,普通的行鎖機制。

在這裏插入圖片描述
執行該條語句
在這裏插入圖片描述
鎖住的就只是id爲4的這一行。

間隙鎖

間隙鎖:主要就是鎖住不存在記錄鎖的其他範圍的。

例如
在這裏插入圖片描述
圖中紅色標記的地方就是間隙鎖的範圍。

主要就是防止插入如果鎖住id = 6,就會鎖住區間(4,7)插入5 , 6都會失敗,但是可以在這個區間再次加入一個排它鎖,因爲沒有數據,排斥沒有意義,所以不排斥,如果鎖住id>20他會默認鎖住(10,+無窮),鎖住的區間臨界肯定是一個記錄數據。

注意:間隙鎖的特點,就是防止進行插入操作,注意的是間隙鎖的區間是雙開區間,一頭必須有一個記錄,但是不包含這個記錄,解決了幻讀的問題,這也是InnoDB不會出現幻讀的問題

臨鍵鎖

臨鍵鎖:主要就是鎖住範圍和記錄。對於存在並且不存在的同時加鎖,臨鍵鎖包含記錄鎖和間隙鎖。
在這裏插入圖片描述
主要鎖住的就是一個左開右閉的一個區間(左開是一個記錄,右閉也是以個記錄)。

執行以下語句
在這裏插入圖片描述

雖然是鎖的是5-9,但是他會找到左邊的臨近的記錄,以及右邊的記錄,如果你加的是6-8的鎖,它底層也是鎖的是(4,7]和(7,10]。

爲什麼可重複讀和已提交讀都使用了MVCC,但是可重複讀解決了幻讀,但是已提交讀並沒有解決幻讀?

第一、可重複讀和已提交讀快照的建立時間不一樣
可重複讀建立快照的時間是獲得的是第一次進行讀取的數據。
已提交讀建立快照的時間是獲得當前之前的數據,如果進行再次查詢,兩次查詢的期間可能被其他的事務進行了增加/刪除,才導致了幻讀。

第二雖然可重複讀和已提交讀都有記錄鎖,間隙鎖,臨鍵鎖,但是可重複讀這三個鎖都比較常用,但是已提交讀大多數都只使用記錄鎖,因爲使用了間隙鎖可以防止數據的插入,也防止了幻讀的現象。

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