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)