Redis基礎(五)—— 事務

這是我參與8月更文挑戰的第7天,活動詳情查看:8月更文挑戰redis

簡介

Redis 事務能夠一次執行多個命令, 而且帶有如下三個重要的保證:緩存

  • 批量操做在發送 EXEC 命令前被放入隊列緩存。
  • 收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其他的命令依然被執行。
  • 在事務執行過程,其餘客戶端提交的命令請求不會插入到事務執行命令序列中。

一個事務從開始到執行會經歷如下三個階段:markdown

  • 開始事務。
  • 命令入隊。
  • 執行事務。

命令

 # 標記一個事務塊的開始
     MULTI
 # 執行全部事務塊內的命令
     EXEC
 # 取消事務,放棄執行事務塊內的全部命令
     DISCARD
 # 取消 WATCH 命令對全部 key 的監視
     UNWATCH
 # 監視一個(或多個)key,若是在事務執行以前這個(或這些)key 被其餘命令所改動,那麼事務將被打斷
     WATCH key [key...]
複製代碼

示例 1:EXEC

multi 開始一個事務,而後將多個命令入隊到事務中,最後由 exec 命令觸發事務,一併執行事務中的全部命令:post

單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增長任何維持原子性的機制,因此 Redis 事務的執行並非原子性的spa

事務能夠理解爲一個打包的批量執行腳本,但批量指令並不是原子化的操做,中間某條指令的失敗不會致使前面已作指令的回滾,也不會形成後續的指令不作。code

 127.0.0.1:6379> set account:a 100
 OK
 127.0.0.1:6379> set account:b 22
 OK
 127.0.0.1:6379> multi
 OK
 127.0.0.1:6379> get account:a
 QUEUED
 127.0.0.1:6379> get account:b
 QUEUED
 127.0.0.1:6379> decrby account:a 50
 QUEUED
 127.0.0.1:6379> incrby account:b 50
 QUEUED
 127.0.0.1:6379> get account:a
 QUEUED
 127.0.0.1:6379> get account:b
 QUEUED
 127.0.0.1:6379> exec
 1) "120"
 2) "22"
 3) (integer) 70
 4) (integer) 72
 5) "70"
 6) "72"
 127.0.0.1:6379> 
 ​
複製代碼

示例 2:DISCARD

取消事務,放棄執行事務塊內的全部命令。orm

multi隊列

...事務

discard字符串

中的全部命令都被取消

 127.0.0.1:6379[1]> set account:a 70
 OK
 127.0.0.1:6379[1]> set account:b  72
 OK
 127.0.0.1:6379[1]> keys *
 1) "account:b"
 2) "account:a"
 127.0.0.1:6379[1]> multi
 OK
 127.0.0.1:6379[1]> set aa 234
 QUEUED
 127.0.0.1:6379[1]> get aa
 QUEUED
 127.0.0.1:6379[1]> discard
 OK
 127.0.0.1:6379[1]> keys *
 1) "account:b"
 2) "account:a"
 127.0.0.1:6379[1]> 
 ​
複製代碼

示例 3:事務的錯誤處理方式1

執行某個命令時報出的錯誤,則只有報錯的命令不被執行,而其餘命令都會執行

如:

key:aa的值是abc,是字符串,沒法自增,執行incr命令就會報錯,但這個報錯不影響其餘命令的執行

 127.0.0.1:6379[1]> multi
 OK
 127.0.0.1:6379[1]> set aa abc
 QUEUED
 127.0.0.1:6379[1]> get aa
 QUEUED
 127.0.0.1:6379[1]> incr aa
 QUEUED
 127.0.0.1:6379[1]> get aa
 QUEUED
 127.0.0.1:6379[1]> exec
 1) OK
 2) "abc"
 3) (error) ERR value is not an integer or out of range
 4) "abc"
 127.0.0.1:6379[1]> 
 ​
複製代碼

示例 4:事務的錯誤處理方式2

隊列中的某個命令出現了報告錯誤,執行時整個的全部隊列都會被取消。

如:

隊列中,出現incr123整個不存在的命令,直接報錯,再執行exec時,也沒法執行整個命令隊列,全部命令都沒有被執行。

 127.0.0.1:6379[1]> keys *
 1) "account:b"
 2) "account:a"
 3) "aa"
 127.0.0.1:6379[1]> multi 
 OK
 127.0.0.1:6379[1]> set bb 123
 QUEUED
 127.0.0.1:6379[1]> get bb
 QUEUED
 127.0.0.1:6379[1]> incr123
 (error) ERR unknown command `incr123`, with args beginning with: 
 127.0.0.1:6379[1]> exec
 (error) EXECABORT Transaction discarded because of previous errors.
 127.0.0.1:6379[1]> keys *
 1) "account:b"
 2) "account:a"
 3) "aa"
 127.0.0.1:6379[1]> 
 ​
複製代碼

示例 5:WATCH

監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動(沒有改動則不影響),那麼事務將被打斷。

redis的watch命令

相關文章
相關標籤/搜索