redis 實戰-redis 事務 1.描述 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事務介紹完畢,有不當地方,歡迎指正!