for update

一、for update定義

for update 是一種行級(jí)鎖,又叫排他鎖。一旦用戶對(duì)某個(gè)行施加了行級(jí)鎖,則該用戶可以查詢也可以更新被加鎖的數(shù)據(jù)行,其它用戶只能查詢但不能更新被加鎖的數(shù)據(jù)行。如果其它用戶想更新該表中的數(shù)據(jù)行,則也必須對(duì)該表施加行級(jí)鎖。即使多個(gè)用戶對(duì)一個(gè)表均使用了共享更新,但也不允許兩個(gè)事務(wù)同時(shí)對(duì)一個(gè)表進(jìn)行更新,真正對(duì)表進(jìn)行更新時(shí),是以獨(dú)占方式鎖表,一直到提交或復(fù)原該事務(wù)為止。行鎖永遠(yuǎn)是獨(dú)占方式鎖。只有當(dāng)出現(xiàn)如下之一的條件,才會(huì)釋放共享更新鎖:
1、執(zhí)行提交(COMMIT)語(yǔ)句
2、退出數(shù)據(jù)庫(kù)(LOG OFF)
3、程序停止運(yùn)行

二、概念和用法

通常情況下,select 語(yǔ)句是不會(huì)對(duì)數(shù)據(jù)加鎖,妨礙其他的 DML和DDL 操作。同時(shí),在多版本一致讀機(jī)制的支持下,select 語(yǔ)句也不會(huì)被其他類(lèi)型語(yǔ)句所阻礙。

select … for update語(yǔ)句是常用的手工加鎖語(yǔ)句。在數(shù)據(jù)庫(kù)中執(zhí)行該語(yǔ)句,會(huì)對(duì)數(shù)據(jù)庫(kù)中的表或某些行數(shù)據(jù)進(jìn)行鎖定。在 MySQL 中,如果查詢條件帶有主鍵索引,會(huì)鎖行數(shù)據(jù);如果條件不是索引鍵,會(huì)鎖表。

由于 InnoDB 預(yù)設(shè)是 Row-Level Lock,所以只有明確的指定主鍵,MySQL 才會(huì)執(zhí)行 Row lock (只鎖住被選取的記錄),否則 MySQL 將會(huì)執(zhí)行 Table Lock(將整個(gè)資料表單給鎖住)。

假設(shè)有張表 user,里面有 id 和 name 兩列,id是主鍵。

1??(明確指定主鍵,并且數(shù)據(jù)真實(shí)存在,row lock)

select * from user where id=3 for update;
select * from user where id=3 and name='Tom' for update;

2??(明確指定主鍵,但數(shù)據(jù)不存在,無(wú)lock)

select * from user where id=0 for update;

3??(主鍵不明確,table lock)

select * from user where id<>3 for update;
select * from user where id like '%3%' for update;

4??(無(wú)主鍵,table lock)

select * from user where name='Tom' for update;

注意:
1、FOR UPDATE 僅適用于 InnoDB,且必須在事務(wù)處理模塊(BEGIN/COMMIT)中才能生效。
2、要測(cè)試鎖定的狀況,可以利用 MySQL 的 Command Mode(命令模式) ,開(kāi)兩個(gè)視窗來(lái)做測(cè)試。
3、Myisam 只支持表級(jí)鎖。InnerDB 支持行級(jí)鎖,添加了(行級(jí)鎖/表級(jí)鎖)的數(shù)據(jù)不能被其它事務(wù)再鎖定,也不被其它事務(wù)修改。是表級(jí)鎖時(shí),不管是否查詢到記錄,都會(huì)鎖定表。

三、什么時(shí)候需要使用for update?

借助 for update 語(yǔ)句,可以在應(yīng)用程序的層面手工實(shí)現(xiàn)數(shù)據(jù)加鎖保護(hù)操作。就是那些需要業(yè)務(wù)層面數(shù)據(jù)獨(dú)占時(shí),可以考慮使用 for update。

場(chǎng)景上,比如火車(chē)票訂票,在屏幕上顯示有票,而真正進(jìn)行出票時(shí),需要重新確定一下這個(gè)數(shù)據(jù)沒(méi)有被其他客戶端修改。所以,在這個(gè)確認(rèn)過(guò)程中,可以使用for update。

四、for update屬于悲觀鎖

悲觀鎖:總是假設(shè)最壞的情況,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)阻塞直到它解鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫(xiě)鎖等,都是在做操作之前先上鎖。就像for update,再比如Java里面的同步原語(yǔ)synchronized關(guān)鍵字的實(shí)現(xiàn)也是悲觀鎖。

樂(lè)觀鎖:顧名思義,就是很樂(lè)觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù),可以使用版本號(hào)等機(jī)制。樂(lè)觀鎖適用于多讀的應(yīng)用類(lèi)型,這樣可以提高吞吐量,像數(shù)據(jù)庫(kù)提供的類(lèi)似于write_condition機(jī)制,其實(shí)都是提供的樂(lè)觀鎖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容