Redis中的樂觀鎖和悲觀鎖

2021-10-08 08:04:27 字數 1843 閱讀 9305

悲觀鎖(pessimistic lock):

顧名思義,就是很悲觀。每次獲取資料的時候,都會擔心資料被修改,所以每次獲取資料的時候都會進行加鎖,確保在自己使用的過程中資料不會被別人修改,使用完成後進行資料解鎖。由於資料進行加鎖,期間對該資料進行讀寫的其他執行緒都會進行等待。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖、表鎖、讀鎖、寫鎖等。都是在操作之前先上鎖讓別人無法操作該資料。

樂觀鎖(optimistic lock):

顧名思義,就是很樂觀。每次獲取資料的時候,都不會擔心資料被修改,所以每次獲取資料的時候都不會進行加鎖,但是在更新資料庫中的資料時需要判斷該資料是否被別人修改過。如果資料被其他執行緒修改,則不進行資料更新,如果資料沒有被其他執行緒修改,則進行資料更新。由於資料沒有進行加鎖,期間該資料可以被其他執行緒進行讀寫操作。

一般使用版本號機制進行判斷。樂觀鎖大多數情況是基於資料版本號(version)的機制實現的。何謂資料版本?即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表新增乙個「version」欄位來實現讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加1。此時,將提交資料的版本號與資料庫表對應記錄的當前版本號進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料,不予更新。

悲觀鎖:比較適合寫入操作比較頻繁的場景,如果出現大量的讀取操作,每次讀取的時候都會進行加鎖,這樣會增加大量的鎖的開銷,降低了系統的吞吐量。

樂觀鎖:比較適合讀取操作比較頻繁的場景,如果出現大量的寫入操作,資料發生衝突的可能性就會增大,為了保證資料的一致性,應用層需要不斷的重新獲取資料,這樣會增加大量的查詢操作,降低了系統的吞吐量。

總結:兩種所各有優缺點,讀取頻繁使用樂觀鎖,寫入頻繁使用悲觀鎖。

像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了效能,所以這種情況下用悲觀鎖就比較合適,之所以用悲觀鎖就是因為兩個使用者更新同一條資料的概率高,也就是衝突比較嚴重的情況下,所以才用悲觀鎖.

悲觀鎖比較適合強一致性的場景,但效率比較低,特別是讀的併發低。樂觀鎖則適用於讀多寫少,併發衝突少的場景。

監視乙個(或多個) key ,如果在事務exec執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

下面這個例子:我們在觀察的時候k1值為1,但是事務執行的時候k1值為2,k1被修改了所以不能執行事務。

127.0

.0.1

:6379

> set k1 1 #設定k1值為1

ok127.0

.0.1

:6379

> watch k1 #監視k1 (當已經開始監控k1,則其他客戶端不能修改k1的值)

ok127.0

.0.1

:6379

> set k1 2 #設定k1值為2,此操作可能由其他客戶端執行

ok127.0

.0.1

:6379

> multi #開始事務

ok127.0

.0.1

:6379

> set k1 3 #修改k值為3

queued

127.0

.0.1

:6379

> exec #提交事務,但k1值不會被修改為3,k1的值仍然是2,因為在事務開啟之前k1的值被修改了

(nil)

127.0

.0.1

:6379

> get k1

"2"

Redis鎖,悲觀鎖和樂觀鎖

樂觀鎖開啟事務前,設定對資料的監聽 watch exec時,如果發生資料發生過修改,作用於改資料的事務會自動取消 discard 事務exec後,無論成敗,監聽會被移除 悲觀鎖每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖。場景 如果專案中使用了快取且對快取設定了超時時間。當併發...

Redis 事務(悲觀鎖 樂觀鎖)

1 定義 redis事務是乙個單獨的隔離操作 事務中所有的命令都會被序列化 按照順序執行 事務在執行過程中不會被其他客戶端傳送來的命令請求打斷 2 作用 串聯多個命令防止別的命令插隊 multi 輸入開始命令 exec 執行命令 discard 放棄組隊 刪除掉 3 注意事項 1 multi 命令不...

樂觀鎖和悲觀鎖

1 悲觀鎖,正如其名,它指的是對資料被外界 包括本系統當前的其他事務,以及來自外部系統的事務處理 修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制 也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無...