Mysql的行級(jí)鎖 -- 共享鎖和排他鎖

在已經(jīng)開啟事務(wù)的前提下:
共享鎖
A用戶使用了共享鎖,B用戶可以使用共享鎖或者不用鎖能查詢到數(shù)據(jù),但是使用排他鎖就會(huì)報(bào)錯(cuò)
A更新數(shù)據(jù),但是會(huì)一直在等待,假如1s后B也更新數(shù)據(jù),這時(shí)就會(huì)陷入死鎖報(bào)錯(cuò)退出。然后A就能更新成功了
排他鎖
A用戶使用了排他鎖,B用戶就使用排他鎖或者共享鎖來獲取數(shù)據(jù),會(huì)一直等待中
A用戶更新數(shù)據(jù)并提交事務(wù),此時(shí)B用戶用戶獲得鎖成功并查得數(shù)據(jù)


InnoDb的鎖的一些注意事項(xiàng)

1. 在不通過索引條件查詢的時(shí)候,InnoDB確實(shí)使用的是表鎖,而不是行鎖

像我們平常通過id查詢這個(gè)就是通過索引條件查詢,因?yàn)橐话銇碚fid都會(huì)做為主鍵,主鍵會(huì)創(chuàng)建索引
如果通過user_name來查詢這個(gè)就不是通過索引條件查詢,除非你給user_name加一個(gè)索引就可以

2. 由于MySQL的行鎖是針對(duì)索引加的鎖,不是針對(duì)記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會(huì)出現(xiàn)鎖沖突的。應(yīng)用設(shè)計(jì)的時(shí)候要注意這一點(diǎn)。
3. 當(dāng)表有多個(gè)索引的時(shí)候,不同的事務(wù)可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會(huì)使用行鎖來對(duì)數(shù)據(jù)加鎖。

行鎖與表鎖的區(qū)別:

行鎖顧名思義標(biāo)識(shí)該條數(shù)據(jù)被鎖,無法被獲得鎖的操作更新或者訪問
表鎖表示整個(gè)表都無法被未獲得鎖的操作更新或者訪問

更深入了解可以看這個(gè)Innodb鎖機(jī)制


以下內(nèi)容為轉(zhuǎn)載

mysql鎖機(jī)制分為表級(jí)鎖和行級(jí)鎖,
行級(jí)鎖中的共享鎖(select ... lock in share mode)與排他鎖(select ...for update)進(jìn)行分享交流

共享鎖又稱為讀鎖,簡(jiǎn)稱S鎖,顧名思義,共享鎖就是多個(gè)事務(wù)對(duì)于同一數(shù)據(jù)可以共享一把鎖,都能訪問到數(shù)據(jù),但是只能讀不能修改。

排他鎖又稱為寫鎖,簡(jiǎn)稱X鎖,顧名思義,排他鎖就是不能與其他所并存,如一個(gè)事務(wù)獲取了一個(gè)數(shù)據(jù)行的排他鎖,其他事務(wù)就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務(wù)是可以對(duì)數(shù)據(jù)就行讀取和修改。

對(duì)于共享鎖大家可能很好理解,就是多個(gè)事務(wù)只能讀數(shù)據(jù)不能改數(shù)據(jù),對(duì)于排他鎖大家的理解可能就有些差別,我當(dāng)初就犯了一個(gè)錯(cuò)誤,以為排他鎖鎖住一行數(shù)據(jù)后,其他事務(wù)就不能讀取和修改該行數(shù)據(jù),其實(shí)不是這樣的。

排他鎖指的是一個(gè)事務(wù)在一行數(shù)據(jù)加上排他鎖后,其他事務(wù)不能再在其上加其他的鎖。mysql InnoDB引擎默認(rèn)的修改數(shù)據(jù)語句,update,delete,insert都會(huì)自動(dòng)給涉及到的數(shù)據(jù)加上排他鎖,select語句默認(rèn)不會(huì)加任何鎖類型,如果加排他鎖可以使用select ...for update語句,加共享鎖可以使用select ... lock in share mode語句。

所以加過排他鎖的數(shù)據(jù)行在其他事務(wù)種是不能修改數(shù)據(jù)的,也不能通過for update和lock in share mode鎖的方式查詢數(shù)據(jù),但可以直接通過select ...from...查詢數(shù)據(jù),因?yàn)槠胀ú樵儧]有任何鎖機(jī)制。

說了這么多,咱們來看下以下簡(jiǎn)單的例子:

我們有如下測(cè)試數(shù)據(jù)

image

現(xiàn)在我們對(duì)id=1的數(shù)據(jù)行排他查詢,這里會(huì)使用begin開啟事務(wù),而不會(huì)看見我關(guān)閉事務(wù),這樣做是用來測(cè)試,因?yàn)樘峤皇聞?wù)或回滾事務(wù)就會(huì)釋放鎖。

打開一個(gè)查詢窗口

image

會(huì)查詢到一條數(shù)據(jù),現(xiàn)在打開另一個(gè)查詢窗口,對(duì)同一數(shù)據(jù)分別使用排他查和共享鎖查詢兩種方式查詢

排他查

image

共享查

image

我們看到開了排他鎖查詢和共享鎖查詢都會(huì)處于阻塞狀態(tài),因?yàn)閕d=1的數(shù)據(jù)已經(jīng)被加上了排他鎖,此處阻塞是等待排他鎖釋放。

如果我們直接使用以下查詢呢

image

我們看到是可以查詢到數(shù)據(jù)的。

我們?cè)倏匆幌乱粋€(gè)事務(wù)獲取了共享鎖,在其他查詢中也只能加共享鎖或不加鎖。

image
image
image

我們看到是可以查詢數(shù)據(jù)的,但加排他鎖就查不到,因?yàn)榕潘i與共享鎖不能存在同一數(shù)據(jù)上。

最后我們驗(yàn)證下上面說的mysql InnoDb引擎中update,delete,insert語句自動(dòng)加排他鎖的問題,

image
image

此時(shí)共享查詢處于阻塞,等待排它鎖的釋放,但是用普通查詢能查到數(shù)據(jù),因?yàn)闆]用上鎖機(jī)制不與排他鎖互斥,但查到的數(shù)據(jù)是修改數(shù)據(jù)之前的老數(shù)據(jù)。

image

然后我們提交數(shù)據(jù),釋放排他鎖看下修改后的數(shù)據(jù),此時(shí)可用排他查,共享查和普通查詢, 因?yàn)槭聞?wù)提交后該行數(shù)據(jù)釋放排他鎖,下面就只顯示普通查詢,其他的同學(xué)們自己去驗(yàn)證。

image
image

可以看到結(jié)果與預(yù)期的一樣。

個(gè)人博客

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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