MySQL鎖

MySQL鎖的類型

這裏講到的MySQL鎖和鎖的類型都是基於InnoDB來說的。併發

共享鎖和排他鎖

共享鎖(shared lock,簡稱S)容許多個讀操做同時進行不相互影響,排他鎖(exclusive lock,簡稱X)會阻塞其它排他鎖請求,直到當前釋放了鎖。優化

意向鎖

意向鎖是InnoDB爲了支持多個粒度上的鎖定提出的概念,可讓行級鎖和表級鎖共存。spa

意向鎖分爲兩種,一種是意向共享鎖(intension shared lock,簡稱IS),一種是意向排他鎖(intension exclusive lock,簡稱IX):3d

  • IS表示一個事務要在這個表加S行鎖
  • IX表示一個事務要在這個表加X行鎖

好比select ... lock in share lock會加IS鎖,select ... for update會加IX鎖。code

在一個事務獲取一張表S行鎖以前,必須對這張表加IS鎖或更高強度的鎖,在一個事務獲取一張表X行鎖以前,必須對這張表加IX鎖,表級別的鎖互斥關係以下所示:blog

 

 結合下面例子理解互斥關係:索引

 

在上面例子裏,現開啓一個事務加了S行鎖,而後對錶加X鎖,會發現對錶加X鎖被阻塞了,結合上面表,能夠分析在加S行鎖的時候,給這張表加了一個IS表鎖,這樣在加X表鎖的時候,由於X表鎖和IS表鎖是互斥的,就致使加X表鎖的操做被阻塞了。事務

總而言之,意向鎖的目的就是爲了加行鎖的時候,在表鎖維度有個標識,表示當前表正在進行一些操做,在加真正的表鎖的時候,就能夠識別這個標識,判斷要加的表鎖是否可以加上。it

記錄鎖

記錄鎖又稱爲行鎖,是InnoDB專門提供的一種鎖,上面例子裏,select * from MyBooks where id = 0 lock in share mode就會加上一個行鎖。io

行鎖會在增、刪、改操做裏自動加上,在查詢操做,能夠顯示加上lock in share mode或for update加上。

行鎖只會對索引行生效,有幾個點須要注意一下:

  • 命中的索引必須是主鍵或者惟一鍵索引
  • 若是SQL語句沒有使用索引或者優化器決定不用索引,那麼就會鎖全表

間隙鎖

間隙鎖是對索引記錄之間、第一個索引記錄以前或者最後一個索引記錄以後的鎖定,不管這個範圍內有沒有這個值,都會被鎖定,間隙可能跨過單個索引值、多個索引值甚至爲空。

間隙鎖有幾個須要注意的點:

  • 若是一個條件命中惟一索引,不會使用間隙鎖
  • 若是明確只查詢一條數據,可是沒有命中惟一索引,會使用間隙鎖鎖定該條索引鍵以前和以後的間隙
  • 間隙鎖的目的是不讓在這個間隙裏插入數據,間隙鎖之間是不排他的,也就是說能夠對同一個間隙加多個間隙鎖
  • 間隙鎖在讀提交級別下不生效

假若有表test,有兩個字端,字段id是惟一鍵索引,字段num是普通索引,有數據:

當事務A對3進行加鎖時,事務B插入(7, 2),(7, 4)會失敗,由於間隙鎖把num索引(1, 3),(3, 5)間隙鎖住了,這時插入(7, 6)是會成功的。

插入(7, 2)是指插入id=7,num=2。 

  

 

臨鍵鎖

臨鍵鎖是記錄鎖和間隙鎖的結合,若是等值條件查詢命中非主鍵索引和非惟一鍵索引,那麼就會命中臨鍵鎖,這是會所這條索引鍵以前和以後的間隙,同時會鎖這條索引鍵。

在上面的例子下,事務B插入(8, 3)會被阻塞。

插入意圖鎖

插入意圖鎖的做用是提升插入操做的併發。若是有多個事務的插入操做等待一段間隙被釋放,會在等待排他鎖時加上插入意圖鎖,等到間隙鎖被釋放時,這多個插入操做不會相互阻塞。

自增鎖

自增鎖是個表級別的鎖,專門處理插入操做自增列,一個事務在執行插入操做時,別的事務的插入操做會阻塞,知道這個插入操做執行完畢,這樣這個插入操做的自增列的數據是連續的。

相關文章
相關標籤/搜索