码迷,mamicode.com
首页 > 其他好文 > 详细

辛星浅谈Redis中的事务

时间:2015-02-20 10:52:51      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:redis   事务   cas   辛星   

     Redis也提供了对事务的支持,在Redis中,我们常用的命令就是multi、exec、discard、watch这四个命令。其中multi命令用于开始一个事务,该语句之后的所有命令都会被视为事务之内的操作,而exec是提交一个事务,discard是回滚一个事务。



      下面是对一些命令的具体介绍:

       multi----用于标记事务的开始,其后执行的命令都被存放于命令队列,直到执行exec时,这些命令才会被原子的执行。它的返回值总是OK。

       exec----执行在一个事务内命令队列中的所有命令,同时将当前连接的状态恢复为正常状态,也就是所谓的非事务状态。如果在事务中执行了watch命令,那么只有当watch所监控的keys没有被修改的前提下,exec命令才能执行事务队列中的所有命令,否则exec将放弃当前事务中的所有命令。它原子性的返回事务中各个命令的返回结果。如果在事务中使用了watch,一旦事务被放弃,那么exec将返回null-multi-bulk这个回复。

        discard--回滚事务队列中的所有命令,同时将当前连接的状态恢复为正常状态,也就是非事务状态。如果watch命令被使用,该命令将unwatch所有的keys。始终返回OK。

        watch---在multi命令执行之前,可以指定待监控的keys,在执行exec之前,如果被监控的keys发生了修改,那么exec将会放弃执行该事务队列中的所有命令。它始终返回OK。

         unwatch----取消当前事务中指定监控的keys,如果执行了exec或者discard命令,则无需手工执行该命令,此时所有被监控的keys都会被自动取消。它始终返回OK。

         

            在Redis的事务中,watch命令可以用于提供CAS功能,所谓CAS就是Check  And Set功能。假设我们通过watch命令在事务执行之前监控了多个keys,加入在我们watch之后有任何的key的值发生了变化,那么exec命令执行的事务都会被放弃,同时返回一个Null  multi-bulk应答以通知调用者事务执行失败。

  

          首先我们看一段代码:

           val  = get  key1

           val  =  val + 1

           set    key1   val

        如果在同一时刻有多个客户端执行上述代码,那么就可能会出现多线程中经常出现的一种问题----竞态争用。比如两个客户端都读取了key1的原有值,如果该值原来为18,那么都执行上述代码后,有可能这两个在读取数据的时候都读到的是18,导致最后的程序得到的结果是19,而不是我们想象中的20.我们使用如下命令则可以避免这个问题:

          watch   key1

          val   =   get   key1

          val   =  val  + 1

          multi  

          set   key1    val  

          exec

          上面我们的代码中,因为watch   key1命令在前面,也就是在获取key1对应的值的时候监控了改建,注意我们这里是把set包围在事务中,如果该值被修改过了,由于watch的存在,那么该操作将会失败,因此我们可以在判断返回值来知道val是否已经被修改过,然后我们可以选择是否需要重新执行该命令。

辛星浅谈Redis中的事务

标签:redis   事务   cas   辛星   

原文地址:http://blog.csdn.net/xinguimeng/article/details/43888139

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!