mysql锁机制(Innodb引擎)
?
InnoDB實(shí)現(xiàn)了兩種類型的行鎖。
共享鎖(S):允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同的數(shù)據(jù)集的排他鎖。
排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù),但是組織其他事務(wù)獲得相同數(shù)據(jù)集的共享鎖和排他鎖。
簡單來說
共享鎖就是我讀的時(shí)候,你可以讀,但是不能寫。
排他鎖就是我寫的時(shí)候,你即不能讀也不能寫。
除此之外InnoDB還有兩個(gè)表鎖:
意向共享鎖(IS):表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入共享鎖,也就是說一個(gè)數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖
意向排他鎖(IX):類似上面,表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入排他鎖,說明事務(wù)在一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。
注意:意向鎖是InnoDB自動加的,不需要用戶干預(yù)。
?
對于insert、update、delete,操作
InnoDB會自動給涉及的數(shù)據(jù)加排他鎖;而對于一般的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
下面我將舉例說明【注意:需要關(guān)閉自動提交事務(wù) set autocommit = 0】
加入共享鎖(我讀的時(shí)候,你可以讀,但是不能寫)
| 事務(wù)1 | 事務(wù)2 |
| 開啟事務(wù) start transaction; ? | 開啟事務(wù) 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; ? |
| 更新此條紀(jì)錄,發(fā)現(xiàn)鎖被占用等待 ? ? 其他事務(wù)退出以后?更新成功 ? ? | 也去更新 導(dǎo)致死鎖退出 ? ? |
| ? | ? |
加入排他鎖 這里就不演示了。
?
具體鎖的實(shí)現(xiàn)原理
?
InnoDB行鎖是通過給索引項(xiàng)加鎖實(shí)現(xiàn)的,如果沒有索引,InnoDB會通過隱藏的聚簇索引來對記錄加鎖。
InnoDB這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過索引條件檢索數(shù)據(jù),InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!
行鎖分為三種情形:
Record lock?:對索引項(xiàng)加鎖,即鎖定一條記錄。
Gap lock:對索引項(xiàng)之間的‘間隙’、對第一條記錄前的間隙或最后一條記錄后的間隙加鎖,即鎖定一個(gè)范圍的記錄,不包含記錄本身 (InnoDB使用間隙鎖的目的,主要為了防止幻讀)
Next-key Lock:鎖定一個(gè)范圍的記錄并包含記錄本身(上面兩者的結(jié)合)。
注意:InnoDB默認(rèn)級別是repeatable-read級別,所以下面說的都是在RR級別中的。
Next-Key Lock是行鎖與間隙鎖的組合,這樣,當(dāng)InnoDB掃描索引記錄的時(shí)候,
當(dāng)我們用范圍條件查詢數(shù)據(jù),會首先對選中的索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙加上間隙鎖(Gap Lock)。如果一個(gè)間隙被事務(wù)T1加了鎖,其它事務(wù)是不能在這個(gè)間隙插入記錄的。
下面舉例說明
假如數(shù)據(jù)庫有以下3條記錄
比如 我要查詢
Select * frm test where id>2 for update,
這個(gè)時(shí)候InnoDB不僅會對符合條件的id值為3的記錄加鎖,也會對id大于3(這些記錄并不存在)的“間隙”加鎖。
注意:::
當(dāng)我們在使用范圍條件檢索并鎖定記錄時(shí),InnoDB這種加鎖機(jī)制會阻塞符合條件范圍內(nèi)鍵值的并發(fā)插入,這往往會造成嚴(yán)重的鎖等待。
因此,尤其是并發(fā)插入比較多的應(yīng)用,
我們要盡量優(yōu)化業(yè)務(wù)邏輯,盡量使用相等條件來訪問數(shù)據(jù),避免使用范圍條件。
?
轉(zhuǎn)載于:https://www.cnblogs.com/javabigdata/p/7612692.html
總結(jié)
以上是生活随笔為你收集整理的mysql锁机制(Innodb引擎)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AndroidStudio工具将Modu
- 下一篇: [NOI2012(bzoj2879)(v