文章目錄
- 是什么
- 能干嘛
- Redis 事務 VS 數據庫事務
- 怎么玩
- 小總結
是什么
-
首先回想一下什么是數據庫的事務?數據庫事務是指作為單個邏輯單元執行的一系列操作,具備以下四個關鍵特性(ACID):
- 原子性(Atomicity):事務中的所有操作要么全部完成,要么全部不完成,不存在部分執行的情況。如果中途出錯,已執行的操作會回滾,確保數據一致性。
- 一致性(Consistency):事務執行前后,數據庫必須保持一致性狀態,即符合預定義的規則和約束。
- 隔離性(Isolation):多個事務并發執行時,彼此互不干擾,每個事務都像是在獨立運行。數據庫通過鎖機制或多版本控制來實現隔離性。
- 持久性(Durability):事務一旦提交,其結果將永久保存在數據庫中,即使系統故障也不會丟失。
-
事務的狀態:
- 活動(Active):事務正在執行。
- 部分提交(Partially Committed):操作執行完畢,但未最終提交。
- 提交(Committed):事務成功完成,結果永久保存。
- 失敗(Failed):無法繼續執行。
- 中止(Aborted):事務回滾,數據庫恢復到事務開始前的狀態。
-
官網:https://redis.io/docs/manual/transactions/
-
可以一次執行多個命令,本質是一組命令的集合,一個事務中的所有命令都會序列化,按順序地串行化執行而不會被其他命令插入,不許加塞
能干嘛
- 一個隊列中,一次性、順序性、排他性的執行一系列命令
Redis 事務 VS 數據庫事務
對比 | 詳細解釋 |
---|---|
單獨的隔離操作 | Redis的事務僅僅是保證事務里的操作會被連續獨占的執行,redis命令執行是單線程架構,在執行完事務內所有指令前是不可能再去同時執行其他客戶端的請求的 |
沒有隔離級別的概念 | 因為事務提交前任何指令都不會被實際執行,也就不存在”事務內的查詢要看到事務里的更新,在事務外查詢不能看到”這種問題了 |
不保證原子性 | Redis的事務不保證原子性(部分支持),也就是不保證所有指令同時成功或同時失敗,只有決定是否開始執行全部指令的能力,沒有執行到一半進行回滾的能力 |
排它性 | Redis會保證一個事務內的命令依次執行,而不會被其它命令插入 |
怎么玩
- 官網 :https://redis.io/docs/manual/transactions/
- 常用命令
-
case1:正常執行
MULTI
、EXEC
-
case2:放棄事務
MULTI
、DISCARD
-
case3:全體連坐,一個語法出錯,全體連坐。如果任何一個命令語法有錯,Redis 會直接返回錯誤,所有的命令都不會執行
-
case4:源頭債主
-
注意和傳統數據庫事務的區別,不一定要么全部成功要么全部失敗
-
case5:watch監控
- Redis使用 Watch 來提供樂觀鎖定,類似于 CAS(Check-and-Set)
- 悲觀鎖:悲觀鎖(Pessimistic Lock),顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。
- 樂觀鎖:樂觀鎖(Optimistic Lock),顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
- 樂觀鎖策略:提交版本必須【大于】記錄當前版本才能執行更新。
- 與悲觀鎖不同,樂觀鎖不會在操作前加鎖,而是在提交修改時檢查數據是否被其他客戶端修改過。如果數據未被修改,則提交成功;否則,操作失敗,客戶端可以選擇重試或放棄。
- CAS
- watch
-
初始化 k1 和 balance 兩個 key,先監控在開啟 multi,保證兩個 key 變動在同一個事務內
-
有加塞篡改:watch 命令是一種樂觀鎖的實現,Redis 在修改的時候會檢測數據是否被更改,如果被更改了,則執行失敗
-
- unwatch
- Redis使用 Watch 來提供樂觀鎖定,類似于 CAS(Check-and-Set)
-
小結:
- 一旦執行了 exec 之前加的監控鎖都會被取消掉
- 當客戶端連接丟失的時候(比如退出鏈接),所有東西都會被取消監視
小總結
- 開啟:以 multi 開始一個事務
- 入隊:將多個命令入隊到事務中,接到這些命令并不會立即執行,而是放到等待執行的事務隊列里面
- 執行:有 exec 命令觸發事務