mysql行表鎖

表鎖

打開兩個session連接數據庫:

先建表插入數據:

create table mylock(
	id int not null primary key auto_increment,
	name varchar(20)
)engine=myisam;


insert into mylock(name) values('a');
insert into mylock(name) values('b');
insert into mylock(name) values('c');
insert into mylock(name) values('d');
insert into mylock(name) values('e');

這裏的引擎是myisam。因爲表鎖主要偏向myisam。一鎖就鎖整張表。

讀鎖

mylock加上讀鎖session1)。

此時兩個對數據庫的session都能夠完成“讀”。

(之後我們稱執行lock table mylock read的session爲session1,就是一個cmd窗口;另一個cmd窗口稱爲session2)。

現在session1嘗試update。

始作俑者改不了。

但是:

session2update的時候阻塞了。

之後當session1解鎖之後:

session2纔會更新成功:


這就是鎖表的壞處。人家要改數據,還得等着你先把表給解鎖了。

同樣的,insert也會阻塞:

寫鎖

session1mylock表加上寫鎖:

看看session1的讀寫情況:


能讀能改。

打開session2


連讀都阻塞住了。

這是萬萬不可的,如果連讀都不能讀,那就什麼操作都無法進行。

這裏我們就可以理解爲什麼寫鎖被稱作獨佔鎖

同時,我們也能理解myisam爲什麼被稱作偏讀的引擎。


行鎖

建表:

我給兩個字段都加上了索引。

插入一些數據:

現在我開兩個session,希望同時對id=5的這一行進行update。

session1:

修改成功。

session2:

阻塞住了。

session1commit

session2解除了阻塞並查看:

可以看到他等了4秒多。

session2commit並查看:

可以看到,mysql確實保證了可重複讀。

而且,innodb默認的行鎖保證了併發操作同一條數據時的先後性。

再開第三個session,它作爲旁人來看:


它看到的是最終修改後的結果(5002),這是合理的。


如果兩個人操作不同的數據,那是互不影響的:

另一方面,如果索引失效,則會直接卡死:


我的value是varchar型的,並且建了索引。我使用了7000這個數值,會使索引失效。這將導致阻塞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章