Redis-rb乐观锁功能异常,测试案例未按预期执行
Redis Watch+Multi事务失效问题解决
你代码里的核心问题是在multi块中错误地直接调用了redis实例的set方法,而没有使用multi块提供的setup对象来执行命令。
问题原因
Ruby的redis gem中,multi块的参数(也就是你代码里的setup)才是事务上下文对象,只有通过它调用的命令才会被加入事务队列,等待后续的EXEC执行。你直接用redis.set的话,这个命令会立即发送给Redis执行,完全绕开了multi的事务机制,自然也不受watch的约束。哪怕watch的键已经被修改,这个set还是会直接覆盖值。
修正后的代码
redis = Redis.new thread = Thread.new do redis.watch("test_case") do sleep 20 redis.multi do |setup| # 改用setup对象调用set,将命令加入事务队列 setup.set "test_case", "foo" end end end
验证效果
修正后,在sleep期间执行:
redis.set "test_case", "bar"
watch会检测到键被修改,后续的事务EXEC会被Redis拒绝,最终test_case的值会保持为"bar",符合预期。
为什么redis-cli测试正常
在redis-cli里,你是严格按照WATCH → MULTI → 加入命令 → EXEC的流程操作的,所有命令都是事务的一部分,所以watch能正常触发阻止事务执行。而你的Ruby代码因为误用了命令调用方式,跳过了事务队列,导致watch失效。
内容的提问来源于stack exchange,提问作者user3829444
相关产品推荐
相关产品推荐

