什么是排他鎖、共享鎖、意向鎖
共享鎖
共享鎖,又被稱為讀鎖,是由讀取操作所創建的一種鎖。在此期間,其他用戶可以同時讀取數據,但在數據上未釋放所有共享鎖之前,任何事務均無法對其進行修改(即獲取數據的排他鎖)。
一旦事務T對數據A加上共享鎖,其他事務只能對A再加共享鎖,而無法加排他鎖。獲得共享鎖的事務僅可讀取數據,不可修改數據。
SELECT ... LOCK IN SHARE MODE;
在查詢語句后增加LOCK IN SHARE MODE,MySQL會對查詢結果中的每一行都加上共享鎖。當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請共享鎖;否則會被阻塞。其他線程也可以讀取已被共享鎖保護的表,且這些線程讀取的是同一版本的數據。
排他鎖
排他鎖又稱為寫鎖。如果事務T對數據A加上排他鎖,則其他事務無法對A加任何類型的鎖。獲得排他鎖的事務既能讀取數據,又能修改數據。
SELECT ... FOR UPDATE;
在查詢語句后增加FOR UPDATE,MySQL會對查詢結果中的每一行記錄都加上排他鎖。只有在沒有其他線程對查詢結果集中的任何一行使用排他鎖時,才能成功申請排他鎖;否則會被阻塞。
意向鎖
在MySQL的InnoDB引擎中,支持多種鎖級別,其中包括行級鎖和表級鎖。當多個事務需要訪問同一共享資源時,如果每個事務都直接請求獲取鎖,可能會發生相互阻塞的情況,甚至可能導致死鎖的產生。
舉個例子:
假設事務A對表Table1中的某一行加上了行級鎖,這使得該行記錄只能被讀取而不能被修改。同時,事務B試圖對Table1增加表級鎖。如果事務B成功獲取了表級鎖,那么它就可以修改表中的任意一行記錄,這就導致了沖突。
為了解決這個問題,需要讓事務B在嘗試對Table1增加表級鎖之前,先判斷是否有其他事務已經對該表的某行加了行級鎖。但是,事務B顯然不能遍歷整個表的數據逐條進行判斷是否有加鎖。
因此,MySQL引入了意向鎖機制。意向鎖是數據庫管理系統中用于實現鎖協議的一種機制,旨在處理不同鎖粒度(如行鎖和表鎖)之間的并發性問題。這種機制幫助解決了不同鎖粒度之間的并發問題,而對于相同鎖粒度之間的并發問題,可以通過行級互斥鎖來解決。
注意:
- 意向鎖并非直接用于鎖定資源,而是用于通知其他事務,以避免它們在資源上設置不兼容的鎖。
- 意向鎖并非由用戶直接請求,而是由MySQL管理的。
當一個事務請求獲取行級鎖或表級鎖時,MySQL會自動獲取相應表的意向鎖。這樣,其他事務在請求獲取表鎖時,就可以首先基于這個意向鎖來發現是否已經有其他事務加過鎖,并根據該鎖的類型(意向共享鎖/意向排他鎖)來判斷自己是否可以獲取鎖。通過這種方式,可以在不阻塞其他事務的情況下,為當前事務鎖定資源。意向鎖有兩種類型:意向共享鎖和意向排他鎖。
- 意向共享鎖:表示事務打算在資源上設置共享鎖(讀鎖)。通常用于表明事務計劃讀取資源,并希望在讀取時不會有其他事務設置排他鎖。
- 意向排他鎖:表示事務打算在資源上設置排他鎖(寫鎖)。這表示事務計劃修改資源,并不希望有其他事務同時設置共享或排他鎖。
意向鎖是一種表級鎖,在觸發意向鎖的事務提交或回滾后會被釋放。