redis的高階事務CAS 樂觀鎖

2022-03-18 13:27:15 字數 2280 閱讀 8631

樂觀鎖介紹:

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

okredis 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

okredis 127.0.0.1:6379>multi

okredis 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可以同時監控多個鍵,在監控期間只要有乙個鍵被其它客戶端改變,則整個事務回滾。

Redis(八)事務的樂觀鎖

redis中可以採用watch命令加鎖。當watch的key改變加鎖的時候的值的時候,執行對key的操作失敗。redis 六 事務以及分析和實操 這裡因為是累減操作,所以沒影響,那麼如果我們想要同步資料呢?重新set回去100 和 0.採用watch加鎖 這裡加鎖後,鎖定監控wallet的值為100...

Redis 樂觀鎖控制事務

redis對事務的支援比較簡單。redis只能保證乙個客戶端發起的事務命令可以執行,中間不會插入其他事務。因為redis是單執行緒的,所以做到上面這點很容易。一般redis接受到客戶端的命令後會立即執行,但是如果客戶端發起multi命令,redis不會立即執行,而是讓當前連線進入事務上下文,把命令放...

Redis樂觀鎖控制事務

redis對事務的支援比較簡單。redis只能保證乙個客戶端發起的事務命令可以執行,中間不會插入其他事務。但 redis集群不支援事務。因為redis是單執行緒的,所以做到上面這點很容易。一般redis接受到客戶端的命令後會立即執行,但是如果客戶端發起multi命令,redis不會立即執行,而是讓當...