Redis的事務
可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,按順序地串行化執行而不會被其他命令插入,不許加塞。
作用:在一個隊列中,一次性、順序性、排他性的執行一系列命令。
multi:標記一個事務塊的開始,即開啓事務;
exec:執行所有事務塊內的命令,截圖:
;
discard:取消事務,放棄執行事務塊內的所有命令,截圖:
;
事務內如果有一條命令出錯(加入隊列的時候就報錯),則事務內的所有命令都會執行失敗,截圖:
;
事務內將命令加入隊列的時候沒有報錯,而是執行事務的時候報錯,則正確的命令會被提交,如下圖:2到5執行成功,1執行出錯,因爲k1的值不是數值型的(注意和上圖中的區別),由此可見,redis對事務的支持是部分支持。截圖:
;
悲觀鎖/樂觀鎖/CAS:
悲觀鎖:每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖:每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量。
樂觀鎖策略:提交版本必須大於記錄當前版本才能執行更新。
watch key [key…]:監視一個或多個key,如果在事務執行之前這些key被其他命令所改動,那麼事務將被打斷。
實例:信用卡金額:
初始化信用卡可用餘額和欠額,balance表示餘額,debt表示欠額,初始化時balance=100,debt=0,無加塞篡改,先監控,再開啓multi,保證兩筆金額變動在同一個事務內,截圖:
;
有加塞(即中途有人把值篡改了)篡改的情況:當執行完watch的時候,剛好有人在另一個客戶端將balance的值從80改爲了800,如圖:,
然後在接着執行multi,然後同樣balance-20,debt+20,結果事務失敗,成功的時候會返回改變之後具體的值,如圖:(圖中紅色圈起來的部分應該在watch balance,不過在修改值之前效果相同);
unwatch:取消watch命令對所有key的監視。當執行完watch的時候,balance的值剛好被改了,如圖:
,
然後執行unwatch,再執行multi及後邊的操作,結果事務成功,如圖:
;
一旦執行了exec,則之前加的監控鎖都會被取消。