1. 程式人生 > 其它 >MySQL --- 讀書筆記 --- 鎖

MySQL --- 讀書筆記 --- 鎖

2. 併發事務訪問相同記錄的情況

2.1 讀-讀情況

讀取操作並不會對記錄有任何影響,所以允許這種情況的發生

2.2 寫-寫情況

對相同記錄做出改動,在這種情況下會出現髒寫情況,任何一種隔離級別都不允許這種情況的發生,所以多個未提交事務對一條記錄做改動時,都需要排隊執行,排隊的過程是通過實現的。

這個所謂是一個記憶體中的結構,在事務執行之前本來是沒有鎖的,當一個事務想對記錄做改動時,首先看看記憶體有沒有與這條記錄相關聯的鎖結構,當沒有的時候,就會生成一個與之關聯的結構,這稱為獲取鎖成功

然後在這個事務提交之前,另一個事務也想對這條記錄改動時,也會想檢視與之關聯的結構,當發現有鎖時,也會生成一個鎖結構與之關聯,但是需要等待,這稱為獲取鎖失敗

當第一個事務結束後,就會把相應的鎖結構釋放,並檢視是否別的事務在等待,如果有,就會喚醒該事務

2.3 讀-寫或寫-讀情況

當一個事務讀取記錄,另一個事務改動記錄,這種情況下就會出現髒讀不可重複讀幻讀問題

  • 讀寫都加鎖
  • 讀取記錄採用MVCC,改動記錄採用

鎖的不同角度分類

3.1 從資料操作的型別劃分

對於InnoDB來說,讀鎖/寫鎖可以加在表上,也可以在行上

1. 讀鎖/共享鎖

英文S表示,針對同一份資料,多個事務的讀操作同時進行,相互不阻塞

SELECT ... FOR SHARE;

2. 寫鎖/排他鎖

英文X表示,在當前操作未完成前,阻斷其他寫鎖或讀鎖

SELECT ... FOR UPDATE;

3.2 從資料操作的粒度劃分

1. 表鎖

該鎖會鎖定這個張表的記錄,是MySQL中最基本的鎖策略,並不依賴於儲存引擎,它的開銷最小,可以很好的避免死鎖問題,但是隨之而來的鎖競爭發生的概率也會提高,導致併發率大打折扣

  • 表級別的S、X鎖
  • 意向鎖

InnoDB支援多粒度鎖,允許行級鎖與表級鎖共存

  1. 意向鎖是為了協調行鎖和表鎖的關係
  2. 意向鎖是一種不與行級鎖衝突的表級鎖
  3. 表明“某個事務正在某些行持有鎖或該事務準備去持有鎖”
  • 自增鎖
  • 元資料鎖

意向鎖是由儲存引擎維護,使用者無法手動操作,在為資料行加S/X鎖時,會先獲取該資料行所在資料表的意向鎖

意向鎖解決的問題:假設有兩個事務t1和t2,當t2想要給表加上S/X鎖,那麼它需要檢查表中每一行記錄是否存在鎖,但是如果我們有意向鎖,當t1給表中某些記錄加鎖時,首先給表新增意向鎖,然後當t2想要進行表級鎖時,就可以直接知道表中某些記錄被其他事務鎖定了

2. 行鎖

  • 優點:粒度小,發生鎖衝突概率低,併發度高
  • 缺點:開銷大,加鎖慢,容易出現死鎖
  1. 記錄鎖
  2. 間隙鎖

在解決幻讀問題上,當使用的方案時,事務讀取記錄時,幻影記錄還沒新增,我們無法給幻影記錄加上記錄鎖,這時就要用到間隙鎖

假設給一條記錄加上間隙鎖,那麼這條記錄的前邊就不允許插入記錄,或者說當主鍵3和主鍵8之間沒有其他記錄,當給主鍵8這條記錄加上間隙鎖,那麼不允許插入主鍵是3-8之間的記錄

無論是共享間隙鎖或者排他間隙鎖,並不限制其他事務對這條記錄加記錄鎖或者間隙鎖

  1. 臨鍵鎖

當既想鎖定某條記錄,又阻止其他事務在該記錄的前邊間隙插入新記錄,這時就用到臨鍵鎖,它只在InnoDB中的可重複讀的隔離級別下使用,InnoDB的預設鎖就是臨鍵鎖

本質是一個記錄鎖和間隙鎖的合體

  1. 插入意向鎖

InnoDB規定事務在等待的時候也需要在記憶體中生成一個鎖結構

當事務希望插入新記錄時,但是遇到間隙鎖需要等待時,生成一個插入意向鎖,它是一種Gap鎖不是意向鎖

它是一種特殊的間隙鎖,當插入記錄之間不同時,互相不排斥