Redis的事物
Redis的事物
Redis 事物常用命令
multi標記一個事物塊的開始
exec:執行所有事物塊內的命令
discard: 取消事物,放棄執行事物塊的所有命令
watch key [key ...]:
監視一個(或多個)key,如果在事物執行前這個(或這些) key 被其他命令所改動,那麽事務將被打斷。
unwatch取消watch命令對所有key的監控
Redis事物介紹
Redis 事務可以一次執行多個命令, 並且帶有以下兩個重要的保證:
(1)批量操作在發送 EXEC 命令前被放入隊列緩存。
收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其余的命令依然被執行。
(並不回滾)
(2)在事務執行過程,其他客戶端提交的命令請求不會插入到事務執行命令序列中。
Redis的一個事務從開始到執行會經歷以下三個階段:
(1)開始事務。
(2)命令入隊。
(3)執行事務。
案例
(1)正常執行
開啟事物,set一些值,然後執行事物。看看能否獲取到值
(2)放棄事務
開啟事物,set一些值,但是又放棄了。最後看看值是否有修改,值並沒有被修改
(3)全體連坐
開啟一個事物,但是中間出現了語法錯誤,直接報錯了,到後面執行事物也是報錯。最後去拿值也是拿不到的。這種情況就是全體連坐。
(3)冤頭債主
開啟一個事物,做一些set操作,對一個
可以看到前兩個都是成功的,只有後面是失敗的,這裏和關系性數據的事物是不一致的。
關系性數據庫:要麽一起成功,要麽一起失敗
nosql redis:將這命令當做批處理,只有當執行了exec後,才會去操作redis,一條失敗也不會影響其他的。
watch監控(重要)
悲觀鎖/樂觀鎖/CAS(Check And Set)
悲觀鎖
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關系型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖
這個就不解釋了,一看就懂,就是我操作數據時,那麽你們都拿不到,只能等著。
樂觀鎖
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量。
樂觀鎖策略:提交版本必須大於記錄當前版本才能執行更新
解釋一下:就相當於,每條數據都會有一個版本號,當我要去修改時,那麽會判斷當前版本號是否是大於數據庫中的版本號,如果是好,你就可以修改,如果不是,好,只能重新查這條數據再去做修再去提交,如果想要修改就需要這樣循環下去。
watch案例
假設:我有一張信用卡,有可用余額和欠額
可用余額:balance 初始化100
欠額:owe 初始化0
(1)無塞篡改
先監控再開啟multi,保證兩筆金額變動在同一個事務內,余額減去20,前額加20,沒有人在中間修改了那麽事物成功提交。
(1)有塞篡改
初始化余額和欠額後
先監控再開啟multi,保證兩筆金額變動在同一個事務內,余額減去20,欠額加20,中途有人修改余額,假如你老爸給你了10000的余額。
可以看到我在中間事物還沒有提交的時候,新增了10000的余額後再把事物提交,
提交事物後返回的是null,代表沒有提交成功。
總結
(1)監控了key,如果key被修改了,後面一個事務的執行失效
(2)一旦執行了exec之前加的監控鎖都會被取消掉了
(3)Watch指令,類似樂觀鎖,事務提交時,如果Key的值已被別的客戶端改變,
比如某個list已被別的客戶端push/pop過了,整個事務隊列都不會被執行
(4)通過WATCH命令在事務執行之前監控了多個Keys,倘若在WATCH之後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Nullmulti-bulk應答以通知調用者事務執行失敗
Redis的事物