這是我參與8月更文挑戰的第7天,活動詳情查看:8月更文挑戰redis
Redis 事務能夠一次執行多個命令, 而且帶有如下三個重要的保證:緩存
- 批量操做在發送 EXEC 命令前被放入隊列緩存。
- 收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其他的命令依然被執行。
- 在事務執行過程,其餘客戶端提交的命令請求不會插入到事務執行命令序列中。
一個事務從開始到執行會經歷如下三個階段:markdown
# 標記一個事務塊的開始
MULTI
# 執行全部事務塊內的命令
EXEC
# 取消事務,放棄執行事務塊內的全部命令
DISCARD
# 取消 WATCH 命令對全部 key 的監視
UNWATCH
# 監視一個(或多個)key,若是在事務執行以前這個(或這些)key 被其餘命令所改動,那麼事務將被打斷
WATCH key [key...]
複製代碼
以
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>
複製代碼
取消事務,放棄執行事務塊內的全部命令。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]>
複製代碼
執行某個命令時報出的錯誤,則只有報錯的命令不被執行,而其餘命令都會執行
如:
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]>
複製代碼
隊列中的某個命令出現了報告錯誤,執行時整個的全部隊列都會被取消。
如:
隊列中,出現
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]>
複製代碼
監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動(沒有改動則不影響),那麼事務將被打斷。