mysql排它鎖和共享鎖跟隔離級別的關係

2021-10-24 05:27:01 字數 2197 閱讀 8817

兩把鎖缺一不可,innodb 引擎中的四種隔離級別就是用 排他鎖 + 共享鎖 實現的。

下面是個人理解,可能並不嚴謹。

首先說一下併發可能產生的四種問題,如果你還不了解這四個問題,最好拿至少 20 分鐘時間模擬一下場景。

假設有兩個事務a,b,有乙個資源值(一條記錄)是v;另外乙個資源值(多條記錄的集合) vvv。

1.丟失修改:a 修改 v 為 v1, b 修改 v 為 v2。那麼最後 v 是v1 還是 v2 呢?無論結果是什麼,一定只有乙個結果,那麼另外乙個修改就丟失了,因此叫做丟失修改。

2.髒讀:a 修改 v 為 v1, 但是修改不成功,事務會回滾。 在事務 a 回滾的時候,b去讀取 v 的值,讀到的值是什麼? 是 v1。 我們的 b 事務想期望的值是 v, 但是卻讀到了 v1,v1是乙個髒資料,因此我們簡稱髒讀。

3.不可重複讀:這個場景下,a 事務要讀兩次 v 的值。 第一次直接讀取,然後停下,這個時候 b 事務去修改 v 的值為 v1,然後 a 事務再執行它的第二次讀取。第一次讀到的是 v, 第二次讀到的是 v1,乙個事務不同時間讀到的值不一樣,這個就是不可重複讀。

4.幻讀:這個場景的資源值不再是乙個記錄了,而是很多記錄的乙個集合,我們叫它 vvv(假設有三條記錄,分別為 v1,v2,v3)。a 事務讀到了 vvv 集合,再使用它之前,b 事務把集合中的 v3 值刪除了,這個時候我們去使用這個集合中的 v3, 但是發現值不在這裡了,我們所讀到的集合就是乙個不真實的集合。幻讀的資源一定要是乙個集合,修改(刪除也被認為是一種修改)會導致集合變化。

針對這四種問題,mysql有四種不同的隔離級別,不同的隔離級別解決的問題不一樣。

1.讀未提交:解決丟失修改的問題。由上面可知,兩個事務同時修改乙個資源值的時候,會發生修改丟失的問題。這個時候我們對資源加乙個排他鎖,加鎖以後,資源只能由乙個事務所擁有,修改完畢以後另外乙個事務才可以拿到資源。這就解決了丟失修改的問題。(資源值加 x 鎖,事務結束釋放)。

2.讀提交:解決髒讀問題。在 1 的基礎上(給資源加 x 鎖,直到事務結束),增加乙個 s 鎖。 讀資料的時候給資料加乙個 s 鎖, 資源在有 x 鎖的時候,s 鎖是加不上去的,因此直到事務結束, s 鎖才可以加上去, 事務都結束了,自然不會讀到髒資料。(寫資料加 x 鎖,事務結束釋放,讀資料加 s 鎖,讀完資料立即釋放)

a.第一次讀,加 s 鎖,得到 v,釋放 s 鎖;

b. 然後 b 事務修改 v 為 v1,加了 x 鎖,事務結束後釋放;

c.第二次讀,加 s 鎖,得到 v1,釋放 s 鎖。

是不是不可重複的問題還是存在?怎麼解決呢? 將我們的 s 鎖設定為,乙個事務結束後才釋放。 加了這個限定條件以後, b 事務就無法修改 v, 因為 v 現在加了 s 鎖,只能被讀,無法被修改。(寫資料加 x 鎖,事務結束釋放,讀資料加 s 鎖,事務結束釋放)

4.序列化,序列化是事務完全按照 acid 的四個原則來執行,這種情況效率比較低,很少用。

這樣一說了,你覺得共享鎖還是多餘的嗎?

再針對具體問題做乙個解釋。

select *from table_name for update; // 加 x 鎖

select *from table_name for share; // 加 s 鎖,mysql 版本 8.0 以後。

select *from table_name lock in share mode; 加 s 鎖, mysql 版本 8.0 以前。

示例: 1. 首先開始乙個事務a,並且關閉自動提交。

start transaction;

set autocommit = 0;

2. 然後在查詢條件下加一把 x 鎖

select	*from table_name for update;
3. 接下來你再開乙個查詢視窗,開不開事務都沒關係,給查詢加一把 s 鎖

select *from person lock in share mode; // 我的版本是 mysql 5.6
執行這條查詢 sql 的時候,就會被堵塞。原因是你在 事務a 中給表加了 x 鎖,再給表加 s 鎖的時候就會堵塞。

當然,你可以先加 s 鎖,再去加 x 鎖的時候同樣會被堵塞。

總結,a視窗加不管是x鎖還是s鎖,b視窗都是可以select到的,但是select的同時要加鎖,就會阻塞。

共享鎖和排它鎖

首先了解的是共享鎖和排它鎖都屬於悲觀鎖。是悲觀鎖的不同實現。共享鎖 讀鎖,是讀取操作建立的鎖,其他使用者可以併發的讀取資料,但任何事務都不能對資料進行修改,知道釋放了共享鎖。如果事務t對資料a加上共享鎖以後,其他事務只能對資料a加共享鎖,不能加排它鎖,獲取共享鎖的事務只能讀取資料,不能修改資料。排它...

共享鎖和排它鎖

共享鎖 s鎖 如果事務t對資料a加上共享鎖後,則其他事務只能對a再加共享鎖,不能加排他鎖。獲准共享鎖的事務職能讀取資料,不能修改資料。排他鎖 x鎖 如果事務t對資料a加上排他鎖後,則其他事務不能在對a加任何型別的封鎖。獲准排他鎖的事務既能讀取資料,也能修改資料。資料庫死鎖的原因 若干事務相互等待對方...

mysql 的共享鎖 排它鎖

當我們在運算元據庫時,可能由於多使用者併發導致資料不一致性。而鎖的出現就是通過禁止某些操作在一段時間之內來避免這種資料的不一致性。又稱讀鎖 s 對某一資源加共享鎖,自身可以讀該資源,其他人也可以讀該資源 也可以再繼續加共享鎖,即 共享鎖可多個共存 但無法修改。要想修改就必須等所有共享鎖都釋放完之後。...