7 Redis 事务
文章目錄
- 1 Redis 事務的定義
- 2 Multi、exec、discard
- 2.1 multi 開啟事務,exec 提交事務
- 2.2 multi 開啟事務,discard放棄事務
- 3 事務的錯誤處理
- 3.1 組隊中出現了錯誤
- 3.2 執行時出現了錯誤
- 4 事務沖突的問題
- 4.1 樂觀鎖
- 4.2 悲觀鎖
- 4.3 Watch key
- 4.3.1 樂觀鎖案例
- 5 事務的三個特性
- 5.1 單獨的隔離操作
- 5.2 沒有隔離級別的概念
- 5.3 不保證原子性
1 Redis 事務的定義
Redis 事務是一個單獨的隔離操作:事務中的所有命令都會序列化、順序執行。事務在執行過程中,不會被其他客戶端發送過來的命令請求所打斷。
Redis 事務的主要作用就是串聯多個命令防止別的命令插隊。
2 Multi、exec、discard
從multi 命令開始,輸入的命令都會依次進入命令隊列中,但不會執行,知道輸入exec后,redis會將之前的命令隊列中的命令依次執行。
組隊的過程中可以通過discard 來放棄組隊。
2.1 multi 開啟事務,exec 提交事務
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set key1 value1 QUEUED 127.0.0.1:6379(TX)> set key2 value2 QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) OK 127.0.0.1:6379>2.2 multi 開啟事務,discard放棄事務
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set a1 v1 QUEUED 127.0.0.1:6379(TX)> set a2 v2 QUEUED 127.0.0.1:6379(TX)> discard OK 127.0.0.1:6379>3 事務的錯誤處理
3.1 組隊中出現了錯誤
組隊中某個命令出現了錯誤,執行時整個隊列都會被取消。
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set b1 v1 QUEUED 127.0.0.1:6379(TX)> set b2 v2 QUEUED 127.0.0.1:6379(TX)> set b3 (error) ERR wrong number of arguments for 'set' command 127.0.0.1:6379(TX)> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get b1 (nil) 127.0.0.1:6379>3.2 執行時出現了錯誤
如果執行階段某個命令報出了錯誤,則只有報錯的命令不會被執行,其他命令都會執行,不會回滾。
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set c1 v1 QUEUED 127.0.0.1:6379(TX)> incr c1 QUEUED 127.0.0.1:6379(TX)> set c2 v2 QUEUED 127.0.0.1:6379(TX)> exec 1) OK 2) (error) ERR value is not an integer or out of range 3) OK 127.0.0.1:6379>4 事務沖突的問題
4.1 樂觀鎖
樂觀鎖(Optimistic Lock) 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用于多讀應用類型,這樣可以提高吞吐量。Redis就是利用這種check-and-set 機制實現事務的。
4.2 悲觀鎖
悲觀鎖(Pessimistic Lock) 顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次拿數據的時候都會上鎖,這樣別人想拿這個數據就會block(阻塞)直到它拿到鎖。傳統的關系型數據庫里面就用到了很多這種鎖機制,比如行鎖,表鎖,讀鎖,寫鎖等,都是在操作之前先上鎖。
4.3 Watch key
在執行multi 之前,先執行watch key [key…],可以監視一個或多個key,如果在事務執行之前這個key 被其他命令所改動,那么事務將被打斷。
4.3.1 樂觀鎖案例
開啟兩個事務,watch監視同一個key,第一個事務執行完成后,第二個key執行會失敗。
先在第一個客戶端設置一個key為blance
127.0.0.1:6379> set blance 100 OK 127.0.0.1:6379> keys *1) "c1"2) "key2"3) "VerifyCode18771105555:count"4) "key1"5) "names"6) "china"7) "c2"8) "sname"9) "k1" 10) "k2" 11) "blance" 12) "name" 13) "user" 14) "k11"在第二個客戶端也可以看到這個key
127.0.0.1:6379> keys *1) "c1"2) "key2"3) "VerifyCode18771105555:count"4) "key1"5) "names"6) "china"7) "c2"8) "sname"9) "k1" 10) "k2" 11) "blance" 12) "name" 13) "user" 14) "k11"兩個客戶端同時開啟watch監控balance 這個key,并同時開啟事務
127.0.0.1:6379> watch balance OK 127.0.0.1:6379> multi OK在第一個客戶端對balance進行自加10并執行事務,成功
127.0.0.1:6379(TX)> incrby balance 10 QUEUED 127.0.0.1:6379(TX)> exec 1) (integer) 10 127.0.0.1:6379>在第二個客戶端對balance進行自加20 并執行事務,失敗
127.0.0.1:6379(TX)> incrby balance 20 QUEUED 127.0.0.1:6379(TX)> exec (nil) 127.0.0.1:6379>因為在第二客戶端執行時,version版本已經被第一個客戶端更新,所以失敗。
5 事務的三個特性
5.1 單獨的隔離操作
事務中的所有命令都會序列化、按順序執行。事務在執行過程中,不會被其他客戶端發送來的命令請求所打斷。
5.2 沒有隔離級別的概念
隊列中的命令沒有提交之前都不會實際被執行,因為事務提交之前任何指令都不會被被實際執行。
5.3 不保證原子性
事務中如果有一條命令執行失敗,其后的命令仍然會被執行,沒有回滾。
總結
以上是生活随笔為你收集整理的7 Redis 事务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6 Springboot 整合Redis
- 下一篇: 8 Redis 持久化RDB