1. 程式人生 > 其它 >聊一聊資料庫中的鎖分類(樂觀鎖、悲觀鎖、共享鎖、排它鎖、表級鎖、行級鎖、頁面鎖)

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

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

樂觀鎖:樂觀鎖就如同他的名字一樣,非常了樂觀,每次去讀資料都認為其它事務沒有在寫資料,總是認為別人不會修改資料,所以就不上鎖,只有在執行緒提交資料時會通過檢查版本號的形式檢測資料有沒有被修改過。一般會在資料表中新增版本號(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)系統。

擴充套件資訊:

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

鎖衝突:一個程序等待另一個程序釋放需要的鎖。

如有錯誤,歡迎指正!