MySQL的共享鎖和獨佔鎖

大雄45發表於2022-03-08
導讀 當有人在更新資料時,其他事務可以讀取這行資料嗎?需要加鎖嗎?

多個事務同時更新一行資料,都會加鎖,然後排隊等待,必須一個事務執行完畢提交了,釋放鎖,才能喚醒下一個事務繼續執行。那這多個事務執行時,加的啥鎖?

MySQL的共享鎖和獨佔鎖MySQL的共享鎖和獨佔鎖

是X鎖,Exclude獨佔鎖,當有一個事務加了獨佔鎖,此時其他事務再想更新這行資料,都要加獨佔鎖,但只能暫時生成獨佔鎖並在後面等待。

當有人在更新資料時,其他事務可以讀取這行資料嗎?需要加鎖嗎?

不用,因為預設情況下,有人在更新資料時,然後你要去讀取,直接預設就是開啟MVCC。即此時對一行資料的讀、寫兩個操作預設不會加鎖互斥,因為MySQL的MVCC就是為此設計,避免頻繁加鎖互斥。

此時你讀取資料,完全可以根據你的ReadView,去undo log版本鏈條裡找個你能讀的版本,而完全不用顧慮別人是否在更新。

就算你真的等他更新完畢並提交了,基於MVCC,你也讀不到他更新的值!因為ReadView機制不允許,所以你預設情況下的讀,完全無需加鎖,不需要去關心其他事務的更新加鎖問題,直接基於MVCC讀某個快照即可。

萬一要是你在執行查詢操作時,偏想加鎖呢?

也可以滿足你,MySQL支援共享鎖,S鎖,語法如下:

select * from table lock in share mode

在查詢語句後面加上lock in share mode,意思就是查詢的時候對一行資料加共享鎖。若此時有別的事務在更新這行資料,已經加了獨佔鎖,此時你的共享鎖還能加嗎?

若你先加了共享鎖,然後別人來更新要加獨佔鎖行嗎?

當然不行了,此時鎖互斥,他只能等待。

若你在加共享鎖時,別人也加共享鎖呢?
可以的,你們倆都可加共享鎖,共享鎖和共享鎖不互斥。

所以更新資料時,必然加獨佔鎖,獨佔鎖和獨佔鎖互斥,此時別人不能更新; 但若此時你要查詢,預設不加鎖,走MVCC讀快照版本,但你查詢是可以手動加共享鎖的,共享鎖和獨佔鎖互斥,共享鎖和共享鎖不互斥。

一般開發業務系統的時候,其實你查詢主動加共享鎖很少見,資料庫行鎖雖然實用, 但一般不會在資料庫層面做複雜的手動加鎖,反而會用基於redis/zookeeper的分散式鎖來控制業務系統的鎖邏輯。

查詢操作還能加互斥鎖:

select * from table for update

我查出來資料以後還要更新,此時我加獨佔鎖了,其他閒雜人等,都不要更新這資料了!

一旦你查詢時加獨佔鎖,在你事務提交前,任何人都不能更新資料,只能你在本事務裡更新資料,等你提交了,別人才能再更新資料。

總結

本文描述了預設情況下更新資料的獨佔鎖,預設情況下查詢資料的mvcc機制讀快照,然後通過查詢加共享鎖和獨佔鎖的方式,共享鎖和獨佔鎖之間的互斥規則。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2867278/,如需轉載,請註明出處,否則將追究法律責任。

相關文章