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事務介紹完畢,有不當地方,歡迎指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/12767.html
標籤:NoSQL
上一篇:【Redis】入門
