MySQL數據庫——Update和Insert操作是鎖表還是鎖行

概述:

Update和Insert是鎖表還是鎖行,會影響到程序中併發程序的設計。

總結:

(1)Update時,where中的過濾條件列,如果用索引,鎖行,無法用索引,鎖表。按照索引規則,如果能使用索引,鎖行,不能使用索引,鎖表。

(2)Insert時,鎖行。

 

一、Update操作

1. 實驗一

(1)創建表和基礎數據,id是主鍵,如下圖:

(2)在navicat中,新建一個查詢頁面,如下圖:

關閉自動提交,並更新第1條數據,執行上圖中的sql語句。

由於沒有使用commit;進行提交,所以id=1數據的age並沒有被更新爲111。

(3)在navicat中,再次新建一個查詢頁面,如下圖:

關閉自動提交,並修改id=1的數據的age值爲1111,執行上圖中的sql語句,結果如下:

可以看到,無法對id=1的數據進行修改。但是,此時只知道id=1的數據無法修改,無法確定是鎖表還是鎖行。

(4)在navicat中再次新建一個查詢頁面,如下圖:

關閉自動提交,並更新id=2的數據的age列爲222,執行上圖中的sql語句,結果如下:

可以看到,id=2的數據的age被修改。也就是說,update時,where中使用id作爲過濾條件時,只是鎖行,而不是鎖表。

2.實驗二

(1)將表中數據重置爲初始值,如下圖:

(2)以上步驟,將過濾條件,由id改爲name,例如:

由於沒有commit,所以,在執行之後,表中數據並沒有改變。

(3)接着,執行以下語句,如下圖:

(4)查看執行結果

執行失敗。如果只是鎖行,那麼where name='陳二'的數據應該是可以修改的。所以這裏是鎖表。

3.實驗三

(1)將表中數據重置爲初始值,如下圖:

(2)給name列添加索引

ALTER TABLE `tb_user` ADD INDEX index_name ( `name` ) ;

(3)重新執行查詢4的語句,如下圖:

(4)接着,執行查詢5的語句,如下圖:

(5)查看結果

可以看到,where name='陳二'的數據被成功修改,意味着,當name有索引的時候,是鎖行。

4. 結論

(1)實驗一和實驗二,實驗變量是過濾條件where中的列,實驗一是id列(主鍵,有索引),實驗二是name列(沒有索引)。結果是以id列爲過濾條件,也就是使用有索引的列時,只是鎖行,而以name列爲過濾條件,也就是沒有索引的列時,會鎖表。

(2)爲驗證以上結果,實驗三給name列添加普通索引,實驗二和實驗三種,where的過濾條件都是name列,實驗變量是name是否有索引。結果是:有索引,鎖行;無索引,鎖表。同結論(1),驗證完成。

 

二、Insert操作

0.準備

注意,將索引刪除(並沒有影響,但是要減少變量),如下:

ALTER TABLE `tb_user` DROP INDEX index_name;

1. 實驗一

(1)關閉自動提交,insert一條新數據,如下圖:

查看tb_user表,發現並沒有插入。(原因是沒有執行commit。)

(2)再次insert一條新數據(這裏並沒有關閉autocommit),如下圖:

結果如下:

可以看到,插入成功。也就是說id=5被鎖定。之後的insert語句並沒有受到影響。

2. 結論

insert的時候,可以併發執行,之間並不會相互影響。可以理解爲,insert是鎖行,而不會鎖表。

 

三、關於索引

當有多個列時,滿足索引的規則:

1.以下語句會鎖表:

set autocommit = 0;
update tb_user set age = 111
where id = 1 or name = '張三';

2.以下語句會鎖行:

set autocommit = 0;
update tb_user set age = 111
where id = 1 and name = '劉一';

3.結論

符合使用索引時的規則。

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