redis中的transaction

The Little Redis Book一书中,提到了redis中transaction的概念,也就是事务,transaction能够保证以下特性:

The commands will be executed in order
The commands will be executed as a single atomic operation (without another client’s command being executed halfway through)
That either all or none of the commands in the transaction will be executed

然后书中举了一个例子,使用get和set操作来实现一个incr操作,因为incr操作具有原子性,直接使用get和set操作不能保证原子性,因此需要使用transaction。书中首先举了一个transaction错误的使用方法:

redis.multi()
current = redis.get('powerlevel')
redis.set('powerlevel', current + 1)
redis.exec()

一开始我并不明白这段代码为什么是错误的,我觉得它给出的错误原因颇具误导性(当然也可能是我个人理解能力的问题了):

With the code above, we wouldnt be able to implement our own incr command since they are all executed together once exec is called.

一开始我觉得这里提到的“executed together”和上文的“executed in order”有矛盾,因此有些糊涂,直到我亲手执行了这段代码:

irb(main):001:0> require 'redis'
=> true
irb(main):002:0> redis=Redis.new(:host => "localhost", :port => 6379)
=> #<Redis client v3.3.0 for redis://localhost:6379/0>
irb(main):003:0> redis.multi()
=> "OK"
irb(main):004:0> current = redis.get('powerlevel')
=> "QUEUED"
irb(main):005:0> redis.set('powerlevel', current + 1)
TypeError: no implicit conversion of Fixnum into String
        from (irb):5:in `+'
        from (irb):5
        from /usr/bin/irb:12:in `<main>'
irb(main):006:0> current
=> "QUEUED"
irb(main):007:0>

对于get指令,在ruby中进行调用时,由于并没有直接执行该指令,因此无法得到确切的值,因此只是将提示字符串”QUEUED”赋给了current,在后面的set指令中的current + 1操作自然就会出错了。一定要认识到的是:调用了exec()后,ruby不可能回过头来给current赋值,因为命令队列是在redis里实现的,而不是在ruby中实现的。所以我觉得如果作者给出的解释是“the get command is not executed the moment it is called,so the variable current won’t get the correct value”的话就更容易理解了。
至于后面提供的watch指令,就解决了current无法得到正确的值的问题了,因为get指令并不在transaction中,所以会被立即执行,将正确的结果赋给current。其实watch并没有保证下面的两个操作不会被中途打断,只是保证在被中途打断后停止操作(我可能把数据库事务中的原子性和编程中的原子操作混淆了,transaction中的原子性指的是All or Nothing,并不保证指编程中原子操作的不可中断性):

redis.watch('powerlevel')
current = redis.get('powerlevel')
redis.multi()
redis.set('powerlevel', current + 1)
redis.exec()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值