辛星浅谈Redis中的事务

     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是否已经被修改过,然后我们可以选择是否需要重新执行该命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值