13. redis事務操作
13.1事務簡介
原子性(Atomicity)
一致性(Consistency)
隔離性(isolation)
持久性(durabiliby)
ACID
13.2 Redis事務
提供了multi、exec命令來完成
- 第一步,客戶端使用multi命令顯式地開啟事務
- 第二步,客戶端把事務中要執行的指令發送給服務器端,例如set 、get 、lpush,這些指令不會立即執行,進入一個隊列中
- 第三步,客戶端向服務器發送一個命令 exec,來完成事務提交。當服務器端收到這個指令后,實際去執行上一步中的命令隊列.
multi set k1 v1 set k2 v2 set k3 v3 get k1 exec multi set k4 v4 set k5 v5 discard //取消
13.3 Redis的事務處理機制
13.3.1 原子性
第一種情況
- 在執行exec指令前,客戶端發送操作命令有誤,redis會報錯并記錄這個錯誤。此時,還可以繼續發送命令操作,在執行exec命令之后,redis拒絕執行所有提交的指令,返回事務失敗的結果。(保證了原子性)
multi set k1 v1 get k1 v1 set k2 v2 exec 整個隊列失敗
第二種情況
- 向服務器發送指令,其中有指令和操作的數據類型不匹配,放入隊列時并沒有報錯。使用lpop指令操作失敗,但get指令成功了。(不能保證原子性)
multi lpop k1 //失敗 get k1 //成功 exec
第三種情況
- 在執行事務的exec指令時,redis實例發生了故障,導致事務執行失敗
- 如果redis開啟了aof日志,可能會有一部分指令被記錄到AOF日志中,需要使用redis-check-aof 去檢查aof文件,將未完成事務操作從aof清除,從而保證原子性
13.3.2 一致性
- 第一種情況,指令進入隊列時就報錯,整個事務全部被放棄執行,可以保證數據的一致性。
- 第二種情況,進入隊列時沒有報錯,實際執行時報錯,有錯誤的指令不去執行,正確的指令可以正常執行,可以保證數據的一致性
- 第三種情況,exec指令時redis實例發生故障,根據RDB和AOF情況來做判斷
- 如果沒有開啟rdb和aof,數據在重啟后沒有,一致的
- 如果使用了rdb方式,rdb不會在事務執行的時候去保存數據,數據庫也是一致的
- 使用aof日志,如果事務隊列操作記錄沒有進入aof,可以保證一致性。如果已加入了一部分,使用redis-check-aof清除事務中已完成的操作,保證事務的一致性
13.3.3 隔離性
提交exec指令去執行事務,分成exec之前和exec之后兩種情況
并發操作在exec指令前,要實現隔離性的保證 ,需要使用watch機制,否則不能保證隔離性
在事務執行前,相當于有一個監控器,在監控key是否已經被修改過了,如果已修改,則放棄事務執行,避免了事務的隔離性被破壞。如果客戶再次執行,此時,沒有其他客戶端去修改數據,則執行成功。
悲觀鎖:synchronized
樂觀鎖:Atomic原子操作
使用unwatch取消watch命令對所有key的監控。
13.3.4 持久性
redis內存數據庫,取決于持久化配置模式
不開啟rdb和aof,只當作緩存使用,是不能保證持久性
使用rdb,如果在一個事務執行后,下一次的rdb快照還未執行前,redis實例發生故障了,不能保證持久性
使用aof, 配置選項 everysec、always、no,也不能保證持久性
不管redis采用什么配置模式,都不能保證事務的持久性