我們在數據庫執行update語句的時候,到底是鎖表還是鎖行?這裡直接用MySQL上例子測試下。
一、環境準備
1、新建一個表
create table test_update(
id BIGINT not null primary key COMMENT '主鍵ID,雪花算法生成',
name VARCHAR(100) COMMENT '姓名',
user_no VARCHAR(20) COMMENT '用戶編號'
);
2、插入兩條數據
insert into test_update(id,name,user_no)values(1,'張三','001');
insert into test_update(id,name,user_no)values(2,'李四','002');
二、開始測試
場景一:不加索引
開啟事務
sql1:update test_update set name=』張三1』 where user_no in(『001』);
不提交事務
開啟事務
sql2:update test_update set name=』李四1』 where user_no in(『002』);
提交事務
我們發現在sql1不提交事務的情況下,sql2被阻塞了,只有當sql1的事務提交後sql2才會執行成功。
總結:在不加索引的情況下,update語句鎖表。
場景二:加索引
先在user_no加索引
ALTER TABLE test_update ADD INDEX index_name (user_no);
開啟事務
sql1:update test_update set name=』張三1』 where user_no in(『001』);
不提交事務
開啟事務
sql2:update test_update set name=』李四1』 where user_no in(『002』);
提交事務
我們發現在sql1不提交事務的情況下,sql2也執行成功了,也就是sql2不依賴於sql1的事務提交。
總結:在加索引的情況下,update語句鎖行。
場景三:加索引,但是in裏面是複雜查詢
上面的例子in裏面都是確定的值,加入in裏面是查詢出來的呢,如下例子(user_no已經加上索引)
開啟事務
sql1:update test_update set name=』張三1』 where user_no in(select user_no from other_table where id=1);
不提交事務
開啟事務
sql2:update test_update set name=』李四1』 where user_no in(select user_no from other_table where id=2);
提交事務
我們發現在sql1不提交事務的情況下,sql2被阻塞了,只有當sql1的事務提交後sql2才會執行成功,跟場景一結果一樣。
總結:在加索引的情況下,in裏面是不確定的值,update語句鎖表。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/209140.html