數據庫中的共享鎖和排他鎖


以下內容轉自  murphy_gb 博客

共享鎖,又稱為讀鎖,獲得共享鎖之后,可以查看但無法修改和刪除數據。

排他鎖,又稱為寫鎖、獨占鎖,獲得排他鎖之后,既能讀數據,又能修改數據。

為什么要加鎖

很多人都知道,鎖是用來解決並發問題的,那么什么是並發問題呢?並發情況下,不加鎖會有什么問題呢?

拿生活中的洗手間舉例子,每個洗手間都會有一個門,並且是可以上鎖的,當我們進入洗手間之后會把門反鎖,當我們出來之后再把鎖打開。

當門被鎖上之后,其他人只能在門外等待。洗手間之所以要有門鎖,就是為了保護隱私的,避免出現多個人同時進入洗手間的情況。

這和數據庫中的鎖其實是一樣的,為了避免多個事務同時操作數據庫導致數據異常,一般會通過鎖機制解決。

在介紹共享鎖和排他鎖之前,我們先來大個比方,前面已經用了一個洗手間的例子,那么就繼續這個例子。一般情況下,我們進入洗手間有可能做一下幾件事:洗手、化妝、上廁所等,其實只要上廁所這件事是極度隱私的,而其他事沒有那么隱私。

我們可以認為洗手間就是一個數據庫表,而洗手間內部的設施就是數據庫表中的數據。我們每個想要進入洗手間的人都是一個事務,簡單的洗手、化妝等操作可以認為是讀操作,而上廁所操作可以認為是寫操作。

共享鎖

前面簡單介紹了數據庫與洗手間之間的類比關系,那么接下來繼續分析什么是共享鎖。

有些時候,如果我們進入洗手間只是想洗手的話,我們一般不會鎖門。而其他人也可以進來洗手、化妝等。但是,其他人是不可以進來上廁所的。

這就是共享鎖,也叫讀鎖。就是我們對數據進行讀取操作的時候,其實是不會改變數據的值的。

所以我們可以給數據庫增加讀鎖,獲得讀鎖的事務就可以讀取數據了。當數據庫已經被別人增加了讀鎖的時候,其他新來的事務也可以讀數據,但是不能寫。

也就是說,如果事務T對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。

用法

在查詢語句后面增加LOCK IN SHARE MODE,Mysql會對查詢結果中的每行都加共享鎖。

SELECT ... LOCK IN SHARE MODE;

當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請共享鎖,否則會被阻塞。其他線程也可以讀取使用了共享鎖的表,而且這些線程讀取的是同一個版本的數據。

排他鎖

介紹完了共享鎖后,在來說說互斥鎖。

如果我們進入洗手間只是想洗手,那么我們可以允許其他人也進來洗手。但是,如果我們進入洗手間是為了上廁所,那么任何人不能再進來做任何事。

這就是排他鎖,也叫寫鎖。就是我們對數據進行寫操作的時候,要先獲得寫鎖,獲得寫鎖的事務既可以寫數據也可以讀數據。但是,如果數據庫已經被別人增加了排他寫鎖,那么后面的事務是無法在獲得該數據庫的任何鎖的。

也就是說,如果事務T對數據A加上排他鎖后,則其他事務不能再對A加任何類型的封鎖。獲准排他鎖的事務既能讀數據,又能修改數據。

用法

在查詢語句后面增加FOR UPDATE,Mysql會對查詢結果中的每行都加排他鎖

SELECT ... FOR UPDATE;

當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請排他鎖,否則會被阻塞。

加鎖原則

拿MySql的InnoDB引擎來說,對於insertupdatedelete等操作。會自動給涉及的數據加排他鎖;

對於一般的select語句,InnoDB不會加任何鎖,事務可以通過以下語句給顯示加共享鎖或排他鎖。

共享鎖:SELECT ... LOCK IN SHARE MODE;

排他鎖:SELECT ... FOR UPDATE;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM