您的位置:首页 > 数据库 > Redis

redis学习篇(九)-----高级特性之事务处理

2016-08-09 00:00 405 查看
redis目前对事务的处理比较简单,只能保证一个客户端连接发起事务中的命令可以连续的执行,而中间不被插入其他客户端连接的命令。

先看下redis事务中会用到的几个方法

--multi --
标记一个事务块的开始
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 exec 命令原子性地执行。总是返回OK。

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

--discard --
取消事务,放弃执行事务块内的所有命令。如果使用 watch 监视了某些key,discard之后将会取消对这些key的监视,效果等同
unwatch。

--watch key [key1] --
监视一个或多个key,如果在事务执行之前这些key被其他命令改动,则事务被打断。总是返回OK。

--unwatch --
取消 watch 命令对所有key的监视。如果在执行 watch 命令之后,exec 命令或者 discard 命令先被执行了的话,那么就不
需要再执行 unwatch了,因为 exec 命令会执行事务,因此 watch 命令的效果已经产生了;而 discard 命令在取消事务的同
时也会取消所有对key的监视,因此这两个命令执行之后,就没有必要执行 unwatch 了

一般情况下,redis收到客户端连接发来的命令,立刻执行并返回结果。但是当server接收到multi命令时,此连接就进入一个事务上下文,redis把连接发来的命令存入一个队列中。当此连接发出exec命令时,redis才开始按照顺序执行队列中的所有命令,并将所有命令执行的结果打包返回给客户端连接,然后结束事务。

举例说明事务的应用

打开两个server模拟主从服务,在开启事务之前先set name,然后master开启事务,执行下列操作:



slave中查看keys*



可以看出并没有age,name也并没有被更改,直到master中exec之后,才会更新



master中执行exec返回queued中所有执行结果,此时在slave中查询才是事务中执行的结果



当master执行的不是exec而是discard时,就会取消队列总的操作。这个就不做举例。

需要提出的是,在mysql中,事务中如果有执行失败的,可以整个回滚,但是redis中不会回滚。



所以,redis的事务,只是统一执行队列中的命令。

watch的操作

监视某些key,当事务执行之前这些key被改变,则事务终止。指的是,在multi之前,如果这些key中有被修改的话,则multi失败。



可以看到,事务开启之前,name被改变了,所以事务执行失败,age并没有设置成功。但是如果在事务开启之前,使用了unwatch的话,那么事务可以继续执行:



最后需要说的是,当一个事务执行完毕,无论是执行成功还是执行失败,或者是回滚,都会unwatch所有的key:



第一次watch name并改变name之后,事务执行失败,没有继续watch,但是下一个事务可以执行成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis nosql 事务
相关文章推荐