聊一聊數據庫中的鎖分類(樂觀鎖、悲觀鎖、共享鎖、排它鎖、表級鎖、行級鎖、頁面鎖)


 

樂觀鎖和悲觀鎖(從策略上划分)

樂觀鎖:樂觀鎖就如同他的名字一樣,非常了樂觀,每次去讀數據都認為其它事務沒有在寫數據,總是認為別人不會修改數據,所以就不上鎖,只有在線程提交數據時會通過檢查版本號的形式檢測數據有沒有被修改過。一般會在數據表中添加版本號(Version)字段來表示被修改的次數,當數據被修改,version+1,只有在version字段和當前數據庫的version值相同時,才提交成功,其實樂觀鎖相當於一種檢測沖突的手段,可通過為記錄添加版本或添加時間戳來實現。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會對數據進行修改,所以每次讀數據的時候都會上鎖,這樣別人想拿這個數據就會block,直到取出數據。悲觀鎖大多數情況下依靠數據庫的鎖機制實現,以保證操作最大程度的獨占性,但隨之而來的是各種開銷。傳統的關系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

悲觀鎖和樂觀鎖的區別:

兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即如果並發量不大,或數據沖突的后果不嚴重,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生沖突,並發量大或數據沖突后果比較嚴重(對用戶不友好),這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適。

悲觀鎖,從數據開始修改時就將數據鎖住,直到更改完成才釋放鎖。樂觀鎖,直到數據修改完准備提交時才上鎖,完成后釋放。

注意:首先明確一點樂觀鎖和悲觀鎖是一種編程策略,並不是數據庫具有悲觀鎖和樂觀鎖。


共享鎖和排它鎖(從讀寫角度划分)

共享鎖(S鎖,Shared Lock):也叫讀鎖(Read Lock),持有S鎖的事務只讀不可寫。如 SELECT 語句。如果事務T對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。

排它鎖(X鎖,Exclusive Lock):也叫寫鎖(Write Lock),持有X鎖的事務可讀可寫。用於數據修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。如果事務T對數據A加上排他鎖后,則其他事務不能再對A加任何類型的封鎖。直到T對A的鎖解除。獲准排他鎖的事務既能讀數據,又能修改數據。

注意:共享鎖和排它鎖是悲觀鎖的不同的實現,它倆都屬於悲觀鎖的范疇。


表級鎖和行級鎖、頁面鎖(從粒度角度划分)

表級鎖:表級鎖將整個表加鎖,性能開銷最小。用戶可以同時進行讀操作。當一個用戶對表進行寫操作時,用戶可以獲得一個寫鎖,寫鎖禁止其他的用戶讀寫操作。寫鎖比讀鎖的優先級更高,即使有讀操作已排在隊列中,一個被申請的寫鎖仍可以排在所隊列的前列。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低。

行級鎖:行級鎖僅對指定的記錄進行加鎖,這樣其它進程可以對同一個表中的其它記錄進行讀寫操作。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高。

頁級鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。 

特點:

三種鎖各有各的特點,若僅從鎖的角度來說,表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如WEB應用;行級鎖更適合於有大量按索引條件並發更新少量不同數據,同時又有並發查詢的應用,如一些在線事務處理(OLTP)系統。

 

擴展信息:

死鎖: 多個進程互相等待對方鎖的釋放。

鎖沖突:一個進程等待另一個進程釋放需要的鎖。

如有錯誤,歡迎指正!


免責聲明!

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



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