Redis 事務能夠一次執行多個命令, 而且帶有如下兩個重要的保證:redis
一個事務從開始到執行會經歷如下三個階段:緩存
單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增長任何維持原子性的機制,因此 Redis 事務的執行並非原子性的。atom
事務能夠理解爲一個打包的批量執行腳本,但批量指令並不是原子化的操做,中間某條指令的失敗不會致使前面已作指令的回滾,也不會形成後續的指令不作。隊列
實例:事務
以MULTI開始一個事務,而後將多個命令入隊到事務中,最後由EXEC命令觸發事務,一併執行事務中的全部命令。ast
redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days" QUEUED redis 127.0.0.1:6379> GET book-name QUEUED redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series" QUEUED redis 127.0.0.1:6379> SMEMBERS tag QUEUED redis 127.0.0.1:6379> EXEC 1) OK 2) "Mastering C++ in 21 days" 3) (integer) 3 4) 1) "Mastering Series" 2) "C++" 3) "Programming"
Redis事務的基本命令打包
一、MULTI請求
標記一個事務塊的開始,事務塊內的多條命令會按照前後順序被放進一個隊列當中,最後由EXEC命令原子性(atomic)地執行。im
redis 127.0.0.1:6379> MULTI # 標記事務開始 OK redis 127.0.0.1:6379> INCR user_id # 多條命令按順序入隊 QUEUED redis 127.0.0.1:6379> INCR user_id QUEUED redis 127.0.0.1:6379> INCR user_id QUEUED redis 127.0.0.1:6379> PING QUEUED redis 127.0.0.1:6379> EXEC # 執行 1) (integer) 1 2) (integer) 2 3) (integer) 3 4) PONG
二、DISCARDnw
Redis Discard 命令用於取消事務,放棄執行事務塊內的全部命令。
redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> PING QUEUED redis 127.0.0.1:6379> SET greeting "hello" QUEUED redis 127.0.0.1:6379> DISCARD OK
三、EXEC
Redis Exec 命令用於執行全部事務塊內的命令。返回事務塊內全部命令的返回值,按命令執行的前後順序排列。當操做被打斷時,返回空值nil。
四、WATCH key [key...]
Redis Watch 命令用於監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動,那麼事務將被打斷。
五、UNWATCH
Redis Unwatch 命令用於取消 WATCH 命令對全部 key 的監視。
# 事務被成功執行 redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> INCR user_id QUEUED redis 127.0.0.1:6379> INCR user_id QUEUED redis 127.0.0.1:6379> INCR user_id QUEUED redis 127.0.0.1:6379> PING QUEUED redis 127.0.0.1:6379> EXEC 1) (integer) 1 2) (integer) 2 3) (integer) 3 4) PONG # 監視 key ,且事務成功執行 redis 127.0.0.1:6379> WATCH lock lock_times OK redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET lock "huangz" QUEUED redis 127.0.0.1:6379> INCR lock_times QUEUED redis 127.0.0.1:6379> EXEC 1) OK 2) (integer) 1 # 監視 key ,且事務被打斷 redis 127.0.0.1:6379> WATCH lock lock_times OK redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET lock "joe" # 就在這時,另外一個客戶端修改了 lock_times 的值 QUEUED redis 127.0.0.1:6379> INCR lock_times QUEUED redis 127.0.0.1:6379> EXEC # 由於 lock_times 被修改, joe 的事務執行失敗 (nil)