Redis 實現樂觀鎖(watch)


1.悲觀鎖

很悲觀,什么時候都會出問題,無論做什么都加鎖,影響效率。

2.樂觀鎖

  • 很樂觀,任務什么時候都不會出問題,所以不會上鎖,跟新數據的時候去判斷一些,在此期間是否有人修改過這個數據,在Mysql中是利用Version字段實現!在Redis中利用watch命令。
  • 獲取version
  • 更新的時候比較version

3.Redis監測(獲取樂觀鎖並執行)

①正常情況執行成功(單線程):

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money # 監視 money 對象
OK
127.0.0.1:6379> multi #事務正常結束,數據期間沒有發生變動,這個時候就正常執行成功!
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 10
127.0.0.1:6379>   

②多線程執行事務

開啟兩個Redis客戶端

第一客戶端命令入隊后並不執行

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #監視 money對象

OK
127.0.0.1:6379> multi 
OK

127.0.0.1:6379> decrby money 10
QUEUED

127.0.0.1:6379> incrby out 10
QUEUED

127.0.0.1:6379>

 

 

第二個客戶端突然插隊執行

127.0.0.1:6379> get money
"100"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379>

 

 

第一個客戶端在執行事務,會執行失敗!

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #監視 money對象
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> 

 

 使用watch可以當作Redis的樂觀鎖操作!可以理解mysql中的 get version。在執行之前,先獲取是否已經被修改了,如果被修改則執行失敗!!

4.執行失敗的處理

①放棄樂觀鎖(unwatch)

②重新執行(重新監視,獲取最新的鎖)

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 1
QUEUED
127.0.0.1:6379> incrby out 1
QUEUED
127.0.0.1:6379> exec
1) (integer) 999
2) (integer) 1
127.0.0.1:6379>    

 


免責聲明!

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



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