InnoDB中的select .. for update語句

InnoDB中的select .. for update語句:線程

1)select .. for update語句僅適用於InnoDB
2)select .. for update語句必須在事務中才能生效。
3)在執行事務中的select .. for update語句時,MySQL會對查詢結果集中的每行數據都添加排他鎖(行鎖、表鎖),其它線程對鎖定行的 更新、刪除、select .. for update查詢 這3種操做都會被阻塞,通常的select語句不會被阻塞。
4)查看自動提交是否開啓(1表示開啓,0表示關閉,默認開啓): select @@autocommit
5)InnoDB行級鎖的實現:InnoDB的行級鎖是經過在索引上加鎖來實現的,因此只有經過明確的索引來查找數據時纔會使用行級鎖。

排它鎖的選擇:rest

若where條件中明確指定了主鍵,且該行數據存在,則只鎖定該行,故排它鎖爲行鎖(row lock)。
若where條件中明確指定了主鍵,可是該行數據不存在,則不會加鎖。

若where條件中明確指定了索引,且該行數據存在,則只鎖定該行,故排它鎖爲行鎖(row lock)。
若where條件中明確指定了索引,可是該行數據不存在,則不會加鎖。

若where條件中未明確指定主鍵或索引,則會鎖定全表,故排它鎖爲表鎖(table lock)。
注:未明確指定 即 未指定(主鍵/索引) 或 指定的是(主鍵/索引)的範圍

eg: # 只鎖定message_id爲1的行 set autocommit=0; begin; select * from t_message where message_id=1 for update; # message_id爲主鍵 commit;code

# 鎖定全表
set autocommit=0;
begin;
select * from t_message where message_id>1 for update; # message_id爲主鍵
commit;

# 鎖定全表
set autocommit=0;
begin;
select * from t_message where type='good' for update; # good非索引列
commit;


其它線程由於等待(排它鎖)超時而報錯:
update t_message set title='asdf' where message_id=1;
[Err] 1205 - Lock wait timeout exceeded; try restarting transaction
相關文章
相關標籤/搜索