mysql鎖機制(Innodb引擎)

 

InnoDB實現了兩種類型的行鎖。數據庫

共享鎖(S:容許一個事務去讀一行,阻止其餘事務得到相同的數據集的排他鎖。併發

排他鎖(X:容許得到排他鎖的事務更新數據,可是組織其餘事務得到相同數據集的共享鎖和排他鎖。優化

簡單來講spa

共享鎖就是我讀的時候,你能夠讀,可是不能寫。3d

排他鎖就是我寫的時候,你即不能讀也不能寫。blog

除此以外InnoDB還有兩個表鎖:索引

意向共享鎖(IS):表示事務準備給數據行加入共享鎖,也就是說一個數據行加共享鎖前必須先取得該表的IS事務

意向排他鎖(IX):相似上面,表示事務準備給數據行加入排他鎖,說明事務在一個數據行加排他鎖前必須先取得該表的IX鎖。ip

注意:意向鎖是InnoDB自動加的,不須要用戶干預。it

 

對於insertupdatedelete,操做

InnoDB會自動給涉及的數據加排他鎖;而對於通常的Select語句,InnoDB不會加任何鎖(若是沒有鎖 也就是 select …… from where…… (沒有額外加鎖後綴)使用MVCC(multiple-version-concurrency-control)是行級鎖的變種,它在普通讀狀況下避免了加鎖操做,所以開銷更低)可是咱們能夠經過如下語句給select加共享鎖或排他鎖。

 

共享鎖:select * from table_name where ..... lock in share mode

排他鎖:select * from table_name where .....for update

下面我將舉例說明【注意:須要關閉自動提交事務 set autocommit = 0

加入共享鎖(我讀的時候,你能夠讀,可是不能寫

事務1

事務2

開啓事務

start transaction;

 

開啓事務

start transaction;

查詢id=1而且加入共享鎖

select  * from test where id = 1 lock in share mode;

 

查詢id=1而且加入共享鎖

select  * from test where id = 1 lock in share mode;

 

更新此條紀錄,發現鎖被佔用等待

 

 

其餘事務退出之後 更新成功

 

 

也去更新 致使死鎖退出

 

 

 

 

加入排他鎖 這裏就不演示了。

 

具體鎖的實現原理

 

InnoDB行鎖是經過給索引項加鎖實現的,若是沒有索引,InnoDB會經過隱藏的聚簇索引來對記錄加鎖。

InnoDB這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖!

行鎖分爲三種情形:

Record lock :對索引項加鎖,即鎖定一條記錄。

Gap lock:對索引項之間的‘間隙’、對第一條記錄前的間隙或最後一條記錄後的間隙加鎖,即鎖定一個範圍的記錄,不包含記錄自己 InnoDB使用間隙鎖的目的,主要爲了防止幻讀)

Next-key Lock:鎖定一個範圍的記錄幷包含記錄自己(上面二者的結合)。

注意:InnoDB默認級別是repeatable-read級別,因此下面說的都是在RR級別中的。

Next-Key Lock是行鎖與間隙鎖的組合,這樣,當InnoDB掃描索引記錄的時候,

當咱們用範圍條件查詢數據會首先對選中的索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙加上間隙鎖(Gap Lock)。若是一個間隙被事務T1加了鎖,其它事務是不能在這個間隙插入記錄的。

下面舉例說明

假如數據庫有如下3條記錄

好比 我要查詢

Select * frm test where id>2 for update

這個時候InnoDB不只會對符合條件的id值爲3的記錄加鎖,也會對id大於3(這些記錄並不存在)的「間隙」加鎖。

注意:::

當咱們在使用範圍條件檢索並鎖定記錄時,InnoDB這種加鎖機制會阻塞符合條件範圍內鍵值的併發插入,這每每會形成嚴重的鎖等待

所以,尤爲是併發插入比較多的應用,

咱們要儘可能優化業務邏輯,儘可能使用相等條件來訪問數據,避免使用範圍條件。

相關文章
相關標籤/搜索