關於 select for update

作用

for update不僅可以鎖行,也可以鎖表。
僅適用於InnoDB。通常使用該語句對數據進行手工加鎖,避免其他線程對該數據進行修改,造成數據不一致性。

 

鎖的範圍

行鎖:明確指定Id,且數據存在

select * from customer where id = 1124 for UPDATE

表鎖:未指定Id或Id不明確

-- 未指定Id列
SELECT * from customer where name = 1112 for update

-- Id不明確
SELECT * from customer where id <> 11 for update

以上可通過變量innodb_row_lock進行觀察

 

模擬表鎖

線程A,未指定Id列,會造成表鎖

線程B,對id=1的數據加鎖,此時因爲線程A表鎖了,需要等待線程A釋放纔可以加鎖

 

鎖的場景
for update 悲觀鎖,當前線程在處理時,希望別的線程對當前數據無法進行操作。

線程A

BEGIN;

-- 將ID=1的數據鎖住
SELECT * FROM work_order WHERE id = 1 FOR UPDATE;

-- 模擬事物未提交
-- COMMIT;

執行結果,對id=1 的數據進行加鎖,但是未提交事物,此時別的線程只可讀卻無法更改

線程B

BEGIN;

-- 查詢出id=1的數據
SELECT * FROM work_order WHERE id = 1 ;

-- 修改id=1的狀態爲V
UPDATE work_order set `status` = 'V' WHERE id = 1 ;

COMMIT;

執行結果,可以查詢出id=1的數據,修改時會等待線程A釋放鎖,否則會進行等待

 

innodb_row_lock 

Innodb_row_lock_current_waits : 當前等待的鎖的數量

Innodb_row_lock_time:鎖的總時長

Innodb_row_lock_time_avg:每次等待鎖花時間的平均數

Innodb_row_lock_time_max:最大的一次等待鎖花的時間

Innodb_row_lock_waits:一共等待鎖的次數

 

 

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