MySQL - for update 行鎖 表鎖

for update 的作用是在查詢的時(shí)候?yàn)樾屑由吓潘i,當(dāng)一個(gè)事務(wù)的操作未完成時(shí)候,其他事務(wù)可以讀取但是不能寫(xiě)入或更新。
它的典型使用場(chǎng)景是高并發(fā)并且對(duì)于數(shù)據(jù)的準(zhǔn)確性有很高要求,比如金錢(qián)、庫(kù)存等,一般這種操作都是很長(zhǎng)一串并且開(kāi)啟事務(wù)的,假如現(xiàn)在要對(duì)庫(kù)存進(jìn)行操作,在剛開(kāi)始讀的時(shí)候是1,然后馬上另外一個(gè)進(jìn)程將庫(kù)存更新為0了,但事務(wù)還沒(méi)結(jié)束,會(huì)一直用1進(jìn)行后續(xù)的邏輯,就會(huì)有問(wèn)題,所以需要用for upate 加鎖防止出錯(cuò)。

InnoDB行鎖類(lèi)型

行鎖的具體實(shí)現(xiàn)算法有三種:record lock、gap lock以及next-key lock。

  • record lock是專門(mén)對(duì)索引項(xiàng)加鎖;
  • gap lock是對(duì)索引項(xiàng)之間間隙加鎖;
  • next-lock則是前面兩種的組合,對(duì)索引項(xiàng)以及之間的間隙加鎖。

只在可重復(fù)讀或以上隔離級(jí)別下的特定操作才會(huì)取得 gap lock 或 next-key lock,在 Select、Update 和 Delete 時(shí),除了基于唯一索引的查詢之外,其它索引查詢時(shí)都會(huì)獲取 gap lock 或 next-key lock,即鎖住其掃描的范圍。主鍵索引也屬于唯一索引,所以主鍵索引是不會(huì)使用 gap lock 或 next-key lock

for update 的使用方式

for update 僅適用于InnoDB,并且必須開(kāi)啟事務(wù),在begin與commit之間才生效。

select * from table_name where ... for update

select 語(yǔ)句默認(rèn)不獲取任何鎖,所以是可以讀被其它事務(wù)持有排它鎖的數(shù)據(jù)的!

實(shí)踐

InnoDB 既實(shí)現(xiàn)了行鎖,也實(shí)現(xiàn)了表鎖。
當(dāng)有明確指定的主鍵/索引時(shí)候,是行級(jí)鎖,否則是表級(jí)鎖

假設(shè)表 user,存在有id跟name字段,id是主鍵,有5條數(shù)據(jù)。

1. 行級(jí)鎖

明確指定主鍵,并且有此記錄,行級(jí)鎖

SELECT * FROM user WHERE id = 1 FOR UPDATE;
SELECT * FROM user WHERE id = 1 and name = 'segon' FOR UPDATE;
進(jìn)程1 進(jìn)程2
begin;
SELECT * FROM user WHERE id = 1 FOR UPDATE; --
-- UPDATE user SET name = ‘test’ WHERE id = 2; – 成功
-- UPDATE user SET name = ‘test’ WHERE id = 1; – 等待
commit; --
-- 執(zhí)行等待的任務(wù),成功

2. 表級(jí)鎖

無(wú)主鍵/索引,表級(jí)鎖

SELECT * FROM user WHERE name = 'segon' FOR UPDATE;

主鍵/索引不明確,表級(jí)鎖

SELECT * FROM user WHERE id <> 3 FOR UPDATE;
SELECT * FROM user WHERE id LIKE '3' FOR UPDATE;
進(jìn)程1 進(jìn)程2
begin;
SELECT * FROM user WHERE id LIKE ‘3’ FOR UPDATE; --
-- UPDATE user SET name = ‘test’ WHERE id = 1; – 等待
commit; --
-- 執(zhí)行等待的任務(wù),成功

3. 無(wú)鎖

明確指定主鍵/索引,若查無(wú)此記錄,無(wú)鎖

SELECT * FROM user WHERE id = -1 FOR UPDATE;
進(jìn)程1 進(jìn)程2
begin;
SELECT * FROM user WHERE id = -1 FOR UPDATE;
-- UPDATE user SET name = ‘test’ WHERE id = 2; – 成功
commit;

參考博文:
https://segon.cn/mysql-for-update.html

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一. 背景知識(shí) [事務(wù)(Transaction)、隔離級(jí)別、傳播機(jī)制] 二. 步入正題:表鎖和行鎖 1.1. 表鎖...
    Whoami令狐沖閱讀 1,879評(píng)論 1 3
  • mysql走你~~ select * form table where id=? 一條mysql查詢都會(huì)經(jīng)歷些...
    小綿羊你毛不多閱讀 799評(píng)論 0 1
  • 當(dāng)一個(gè)系統(tǒng)訪問(wèn)量上來(lái)的時(shí)候,不只是數(shù)據(jù)庫(kù)性能瓶頸問(wèn)題了,數(shù)據(jù)庫(kù)數(shù)據(jù)安全也會(huì)浮現(xiàn),這時(shí)候合理使用數(shù)據(jù)庫(kù)鎖機(jī)制就顯得異...
    初來(lái)的雨天閱讀 3,696評(píng)論 0 22
  • 為什么要學(xué)習(xí)鎖機(jī)制 鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制。 因?yàn)閿?shù)據(jù)也是一種供許多用戶共享的資源,如...
    Java架構(gòu)師筆記閱讀 1,040評(píng)論 0 7
  • 鎖概述 MySQL的鎖機(jī)制,就是數(shù)據(jù)庫(kù)為了保證數(shù)據(jù)的一致性而設(shè)計(jì)的面對(duì)并發(fā)場(chǎng)景的一種規(guī)則。 最顯著的特點(diǎn)是不同的存...
    胡一巴閱讀 304評(píng)論 0 0

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