redis的高級事務CAS(樂觀鎖)


樂觀鎖介紹:
watch指令在redis事物中提供了CAS的行為。為了檢測被watch的keys在是否有多個clients同時改變引起沖突,這些keys將會被監控。如果至少有一個被監控的key在執行exec命令前被修改,整個事物將會回滾,不執行任何動作,從而保證原子性操作,並且執行exec會得到null的回復。

樂觀鎖工作機制:
watch 命令會監視給定的每一個key,當exec時如果監視的任一個key自從調用watch后發生過變化,則整個事務會回滾,不執行任何動作。注意watch的key是對整個連接有效的,事務也一樣。如果連接斷開,監視和事務都會被自動清除。當然exec,discard,unwatch命令,及客戶端連接關閉都會清除連接中的所有監視。還有,如果watch一個不穩定(有生命周期)的key並且此key自然過期,exec仍然會執行事務隊列的指令。

 

客戶端1 客戶端2 說明
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"

redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
數據庫中兩客戶端登錄,及鍵初始值。
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr age
QUEUED
redis 127.0.0.1:6379> set name lisi
QUEUED
  此時,客戶端1開啟事務,並提交隊列命令:
1.想要將當前age自增+1運算;
2.將name值改為lisi
  redis 127.0.0.1:6379> incr age
(integer) 11


此時,客戶端2修改了age值

redis 127.0.0.1:6379> exec
1) (integer) 12
2) OK

redis 127.0.0.1:6379> get name
"lisi"
  此時,客戶端1執行隊列命令,發現運算之后age不是理想中的11,而是12原因是被其它客戶插足搶先給修改了。name值也修改了。這樣可能導致數據不一致性...

為了解決這個問題引入“樂觀鎖”的機制:
     
     
客戶端1-引入“樂觀鎖”機制 客戶端2 說明
redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"

redis 127.0.0.1:6379> get age
"10"
redis 127.0.0.1:6379> get name
"zhangsan"
數據庫中兩客戶端登錄,及鍵初始值。
redis 127.0.0.1:6379> watch age name
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr age
QUEUED
redis 127.0.0.1:6379> set name lisi
QUEUED
  此時,客戶端1用watch命令監視age和name,然后開啟事務,並提交隊列命令
  redis 127.0.0.1:6379> incr age
(integer) 11

此時,客戶端2修改了age值

redis 127.0.0.1:6379> exec
(nil)
redis 127.0.0.1:6379> get age
"11"
redis 127.0.0.1:6379> get name
"zhangsan"
  此時,客戶端1執行隊列命令,由watch監控發現此期間age的值已經被修改過,則讓事整個務回滾,不做任何動作。

watch可以同時監控多個鍵,在監控期間只要有一個鍵被其它客戶端改變,則整個事務回滾。
     


免責聲明!

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



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