Redis笔记3-redis事务

Redis的事务机制允许同时执行多条指令,它是原子性操作,事务中的命令要么全部执行,要么全部不执行,另外,事务中的所有指令都会被序列化,而且其开始执行过程中,不回被即时过来的指令所打断,其需要经历三个过程,分别为开始事务、命令入队以及执行事务。

 

一、相关命令

1、MULTI

该命令用来开启事务,它总是返回ok结果,当其执行之后,客户端可以继续发送任意条数量的指令,这些指令不会立即被执行,而是被放到了队列中,直到EXEC被调用之后,所有命令才会被序列化执行。

 

2、EXEC

该命令负责触发并执行队列中所有的命令。

 

NOTE:

如果MULTI开启之后,因为某些原因没有成功执行EXEC,那么事务中所有的命令都不会被执行的。

 

3、DISCARD

该命令用来刷新事务中所有排队等待执行的指令,它总是返回ok结果,并且将服务连接状态恢复到正常。如果已经使用WATCH,那么其会将释放所有被WATCH的key。

 

4、WATCH

标记所有指定的key被监控起来,使其在事务中有条件的执行(乐观锁)。

 

NOTE:

A、WATCH使得EXEC命令需要有条件的执行,也就是事务只能在所有被监视的键没有被修改的前提下才能执行。另外,在EXEC被执行之后,所有的WATCH都会被取消。

B、UNWATCH手动取消对所有键的WATCH,如果执行了EXEC或者DISCARD,则不需要手动执行UNWATCH命令

 

redis事务有两种情况:

  1.事务开启期间,发生语法错误,所有事务都会滚。如下图:

第二种,对某个键执行不符合其数据类型的操作:实际上,这就意味着只有程序错误才会导致Redis命令执行失败,这种错误很有可能在程序开发期间发现,一般很少在生产环境发现。

 在事务运行期间,虽然Redis命令可能会执行失败,但是Redis仍然会执行事务中余下的其他命令,而不会执行回滚操作,

如下图:

 

 

WATCH命令详解:Watch命令一个重要的应用就是施加乐观锁

那么WATCH命令实际做了些什么呢?这个命令会使得EXEC命令在满足某些条件时才会运行事务:我们要求Redis只有在所有受监控的键都没有被修改时,才会执行事务。(但是,相同的客户端可能会在事务内部修改这些键,此时这个事务不会中止运行。)否则,Redis根本就不会进入事务。(注意,如果你使用WATCH命令监控一个易失性的键,然后在你监控这个键之后,Redis再使这个键过期,那么EXEC命令仍然可以正常工作。)

WATCH命令可以被调用多次。简单说来,所有的WATCH命令都会在被调用之时立刻对相应的键进行监控,直到EXEC命令被调用之时为止。你可以在单条的WATCH命令之中,使用任意数量的键作为命令参数。

当调用EXEC命令时,所有的键都会变为未受监控的状态,Redis不会管事务是否被中止。当一个客户单连接被关闭时,所有的键也都会变为未受监控的状态。

你还可以使用UNWATCH命令(不需要任何参数),这样便能清除所有的受监控键。当我们对某些键施加乐观锁之后,这个命令有时会非常有用。因为,我们可能需要运行一个用来修改这些键的事务,但是在读取这些键的当前内容之后,我们可能不打算继续进行操作,此时便可以使用UNWATCH命令,清除所有受监控的键。在运行UNWATCH命令之后,Redis连接便可以再次自由地用于运行新事务。

如何使用WATCH命令实现ZPOP操作呢?

本文将通过一个示例,说明如何使用WATCH命令创建一个新的原子化操作(Redis并不原生支持这个原子化操作),此处会以实现ZPOP操作为例。这个命令会以一种原子化的方式,从一个有序集合中弹出分数最低的元素。以下源码是最简单的实现方式:

 

posted @ 2018-03-01 14:20  妮蔻  阅读(...)  评论(...编辑  收藏