MySQL笔记-InnoDB中Record Lock与Gap Lock
鎖:用于在多個事務(wù)訪問同一個對象時根據(jù)這些操作訪問同一對象的先后次序給事務(wù)排序。
?
不同數(shù)據(jù)庫的鎖實現(xiàn):
InnoDB:行級鎖;
Oracle:行級鎖;
MyISAM:表級鎖;
Microsoft SQL Service:行級鎖、鎖升級
?
InnoDB存儲引擎中的鎖:
表級鎖:
IS(意向共享鎖):事務(wù)給行加共享鎖時會先取得該表的IS鎖;
IX(意向排他鎖):事務(wù)給行加排他鎖時必須取得該表的IX鎖;
行級鎖:
S(行級共享鎖):允許一個事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)的排他鎖;
X(行級排他鎖):允許獲取排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)獲取相同數(shù)據(jù)的共享鎖和排他鎖;
?
比如如下這條語句:
update t1 set name = 'aaaaa' where id = 1;這里先回給表t1添加IX鎖,然后再給id=1的行添加X鎖。
下面給出兼容性表格:
這里為什么要用2個鎖:因為在高并發(fā)下,如果有事務(wù)去刪這個表,就會去查有沒有這2個鎖,先找表鎖,再找行鎖。這樣的話效率就高得多。
?
下面是InnoDB行鎖的介紹:
Record Lock:行記錄鎖;
Gap Lock:間隙鎖,在索引記錄間隙上的鎖,在第一條索引記錄之前,最后一條索引記錄之后上的間隙鎖;
Next-key lock:下鍵鎖,上面2個鎖的組合鎖;
?
比如下面這個表:
create table t2(id int, name varchar(10),primary key(id),key(name));insert into t2 values(1, 'A'), (3, 'A'), (5, 'C'), (7, 'G'), (10, 'I'); select id, name from t2;這里有一點要注意:只有可重復(fù)讀的事務(wù)等級才會有Gap lock鎖。對應(yīng)普通索引和普通列。基本上只針對普通索引。在空隙間加鎖,解決幻讀。因為不能插入數(shù)據(jù)。
?
在事務(wù)中常常用到的2組關(guān)鍵字:
for update:可以為數(shù)據(jù)庫中的行上一個排它鎖。當(dāng)一個事務(wù)的操作未完成時候,其他事務(wù)可以讀取但是不能寫入或更新。
lock in share mode:共享鎖,允許其他線程讀,但不能進(jìn)行修改。
?
下面做一個關(guān)于Record Lock的例子:
當(dāng)session 1 進(jìn)行:
begin; select * from t2 where name = 'C' for update;session 2會被阻塞嗎?
begin; select * from t2 where id = 5 lock in share mode;for update為id為5的行加了排他鎖,導(dǎo)致在session2查的時候,阻塞。
但是mysql有套超時解鎖機(jī)制:
當(dāng)超時會把自動釋放事務(wù)。
?
下面是第二個關(guān)于Record Lock的測試:
先來看下t2的所有數(shù)據(jù):
select * from t2;session1:
begin; select * from t2 where id = 5 and name = 'C' for update;session2:
begin; select * from t2 where id = 5 and name = 'B' for update;從中可以看到,也是被阻塞的。
?
這里可以通過這條命令查詢下哪個事務(wù)用了什么鎖:
在mysql中InnoDB中的鎖會被記錄到innodb_locks這個表中:
select * from information_schema.innodb_locks;普通索引上的鎖,都要追溯到主鍵上。mysql是聚蔟索引表。最終會關(guān)聯(lián)到主鍵上。
?
?
下面是關(guān)于Gap Lock的測試
理論我們都知道了,加了Gap Lock,解決幻讀,是不能插入其他數(shù)據(jù)的,在此還是演示下:
session1:
begin; select * from t2 where name = 'C' for updatesession2:
begin; insert into t2 values(4, 'C');查看其阻塞的情況。
這里要知道的一點:Gap lock在InnoDB中存在的條件是事務(wù)等級為可重復(fù)讀,先查下事務(wù)等級:
show variables like '%iso%'演示如下:
從中可以看到session2被阻塞了,看下鎖:
也就是為什么MySQL中可重復(fù)讀,可以解決幻讀問題,但是這種默認(rèn)設(shè)計在理論上來說,并發(fā)量沒有oracle高。但好處也是很多的。
總結(jié)
以上是生活随笔為你收集整理的MySQL笔记-InnoDB中Record Lock与Gap Lock的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Arduino笔记-人体感应灯项目
- 下一篇: Java笔记-spring-rabbit