Redis 序列之一——Redis的事务

           redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。

          (一)redis事务的执行

           一般情况下redis在接受到一个client发来的命令后会立即处理并返回处理结果,但是当一个client在一个连接中发出 multi 命令后,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client,然后此连接就结束事务上下文。例如:


                                        

            发出multi命令后, 再发出incr a和incr b命令并没执行而是被放到了队列中。调用exec后俩个命令被连续的执行,最后返回的是两条命令执行后的结果。

 

            (二)redis事务的取消

             我们可以调用 discard 命令来取消一个事务。
                                         
               可以发现这次incr a incr b都没被执行。 discard命令其实就是清空事务的命令队列并退出事务上下文。  虽说redis事务在本质上也相当于序列化隔离级别的了, 但是由于事务上下文的命令只排队并不立即执行,所以事务中的写操作不能依赖事务中的读操作结果。

 

             (三)实现CAS

             Redis使用乐观锁来实现了CAS(check and set)操作,在redis 2.1后添加了watch命令,可以用来实现Redis事务中的CAS操作。

             watch 监视指定的key,这个key可以有多个。当被watched的key在事务exec前至少有一个发生改变,那么整个事务将跳出,exec命令返回(nil)。

                    

              左图说明:执行watch命令后,在进入事务之前(执行multi命令之前),如果被watch的key(a)没有发生改变,那么事务是有效的,在事务里修改key是会生效的。

              右图说明:执行watch命令后,在进入事务之前(执行multi命令之前),如果被watch的key(a)发生了改变,那么事务就会失效,即事务里对被watch的key进行操作是无效的(其value值不会发生变化)。

 

              (四)redis事务的缺陷

              redis的事务实现是如此简单,当然会存在一些问题。redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令

                  

                  可以看到虽然incr b失败了,但是其他两个命令还是执行了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值