Redis事务

Redis事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务的基础。

  当使用 AOF 方式做持久化的时候, Redis 会使用单个 write(2) 命令将事务写入到磁盘中。然而,如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。使用 redis-check-aof 程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动。

1、Redis Multi 命令-----标记一个事务块的开始,它总是返回 OK 

  MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC 命令被调用时, 所有队列中的命令才会被执行

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

2、Redis Exec 命令-----执行所有事务块内的命令

假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。

可用版本:
>= 1.2.0
时间复杂度:
事务块内所有命令的时间复杂度的总和。
返回值:
事务块内所有命令的返回值,按命令执行的先后顺序排列。 当操作被打断时,返回空值 nil 。  
# 事务被成功执行

redis> MULTI            # 开启事务
OK
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED

redis> EXEC         # 执行
1) (integer) 1
2) (integer) 2
3) PONG


# 监视 key ,且事务成功执行
redis> WATCH lock lock_times
OK
redis> MULTI    # 开始事务
OK
redis> SET lock "huangz"
QUEUED
redis> INCR lock_times
QUEUED

redis> EXEC
1) OK
2) (integer) 1


# 监视 key ,且事务被打断

redis> WATCH lock lock_times
OK
redis> MULTI
OK
redis> SET lock "joe"        # 就在这时,另一个客户端修改了 lock_times 的值
QUEUED
redis> INCR lock_times
QUEUED
redis> EXEC                  # 因为 lock_times 被修改, joe 的事务执行失败
(nil)

3、Redis DISCARD 命令-----取消事务,放弃执行事务块内的所有命令。

如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH 。

可用版本:
>= 2.0.0
时间复杂度:
O(1)。
返回值:
总是返回 OK 。
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

redis 127.0.0.1:6379> GET greeting
(nil)

4、Redis WATCH 命令-----监视一个(或多个) key 。

WATCH key [key ...]

如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

WATCH 命令可以被调用多次。 对键的监视从 WATCH 执行之后开始生效, 直到调用 EXEC 为止。

另外, 当客户端断开连接时, 该客户端对键的监视也会被取消。

使用无参数的 UNWATCH 命令可以手动取消对所有键的监视

可用版本:
>= 2.2.0
时间复杂度:
O(1)。
返回值:
总是返回 OK 。
redis>WATCH key1 key2 key3    # 监控 key1 key2 key3 
 OK

5、Redis不支持roll back回滚

Redis 在事务失败时不进行回滚,而是继续执行余下的命令 

这样做法的优点:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

没有任何机制能避免程序员自己造成的错误, 并且这类错误通常不会在生产环境中出现, 所以 Redis 选择了更简单、更快速的无回滚方式来处理事务。

 

上一篇:Redis 事务


下一篇:Redis-第六章节-事务