redis 實戰-redis 事務

redis 實戰-redis 事務

  1.描述

 

   redis 事務單獨的隔離操作:事務中的所有命令都會序列化、按順序執行。事務在執行過程中,不會被其他客戶端發送過來的命令請求所打斷。

 

  redis 事務沒有隔離級別的概念:隊列中的命令沒有提交之前都不會實際的被執行,因爲事務提交前任何指令都不會被實際執行,也就不存在“事務內的查詢看到事務裏的更新,在事務外查詢不能看到”。

  redis 事務不保證原子性:redis 同一個事務中如果有一條命令運行時執行失敗,其後的命令仍然會被執行,沒有回滾。

 

  

  2.命令

 

  Multi、Exec、Discard和Watch是Redis事務的相關命令。
  Multi:標記一個事務塊的開始。Multi 命令用於開啓一個事務,它總是返回 OK 。 Multi 執行之後, 客戶端可以繼續向服務器發送任意多條命令, 這些命令不會立即被執行, 而是被放到一個隊列中, 當 Exec命令被調用時, 所有隊列中的命令纔會被執行。另一方面, 通過調用 Discard, 客戶端可以清空事務隊列, 並放棄執行事務。

  Exec:執行所有事務塊內的命令。命令的回覆是一個數組, 數組中的每個元素都是執行事務中的命令所產生的回覆。 其中, 回覆元素的先後順序和命令發送的先後順序一致。當客戶端處於事務狀態時, 所有傳入的命令都會返回一個內容爲 Queued 的狀態回覆(status reply), 這些被入隊的命令將在 Exec 命令被調用時執行。

  Discard:取消事務,放棄執行事務塊內的所有命令。當執行Discard命令時,事務會被放棄,事務隊列會被清空,並且客戶端會從事務狀態中退出。

  Watch:監視一個或多少Key,如果在事務執行之前這個或這些Key被其他命令所改動,那麼事務將被打斷。

  UnWatch:取消Watch命令對所有Key的監視。

 

 

  

  3.示例

  3.1.    正常執行示例

  首先我們清空數據庫內容,查看內容能看到數據庫爲空。然後Multi 開啓一事務,設置兩個 Key、Value值,Exec 執行事務。我們看到執行事務時,同時返回兩命令的執行結果。通過查詢數據庫正常保存兩數據內容。

   

  3.2.    放棄事務示例

  接下來,我們再來試下,放棄事務示例,首先我們清空數據庫內容,查看內容能看到數據庫爲空。然後Multi 開啓一事務,設置兩個 Key、Value值,此時,我們執行Discard命令,放棄事務。通過查看數據庫中內空,我們可以看到數據庫中還是爲空。

  

  3.3.    全體連坐示例

  全體連坐指的是什麼呢?就是說其中有一條命令編譯時錯誤,整個系列命令都將不會被執行。

  

  3.4.    冤頭債主示例

  冤頭債主指的是什麼呢?就是說其中有一條命令運行時有問題,系列中沒問題的命令會執行,有問題的命令不會成功執行。

  

  3.5.    Watch監控

  Watch 命令可以爲 Redis 事務提供 check-and-set (CAS)行爲。被 Watch 的鍵會被監視,並會發覺這些鍵是否被改動過了。 如果有至少一個被監視的鍵在 Exec 執行之前被修改了, 那麼整個事務都會被取消, Exec 返回nil-reply來表示事務已經失敗。

  下面我們以信用卡賬號結餘和債務爲例:

  先初始賬號結餘爲100,債務爲0。消費20,賬號結餘減20,債務增加20。首先Watch監視賬號結餘,然後開啓事務,對賬號結餘及債務進行操作。

  當無加塞篡改時,正常執行結果,賬號結餘爲80,債務20。

   

  當Watch監視賬號結餘,有加塞篡改賬號結餘,比如向賬號充值100,賬號結餘改爲180時,再執行一系列命令,執行事務時,得到的結果將是未能正常更新操作。

   

  

  4.總結

  我們發現 Redis 對於事務,部分支持,不能像SQL Server等關係數據庫的強一致性。Watch指令,類似樂觀鎖,事務提交時,如果Key的值已被別的客戶端改變,比如某個List已被別的客戶端Push/Pop過了,整個事務隊列都不會被執行。通過Watch命令在事務執行之前監控多個Keys,倘若在Watch之後有任何Key的值發生了改變,Exec命令執行的事務都將被放棄,同時返回Nullmulti-bulk應答以通知調用者事務執行失敗。

 

  至此Redis事務介紹完畢,有不當地方,歡迎指正!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章