概述:
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.結論
符合使用索引時的規則。