gpt4 book ai didi

ruby - 如何从 Ruby 中的 MULTI block 中的 Redis 读取数据?

转载 作者:IT王子 更新时间:2023-10-29 05:55:28 25 4
gpt4 key购买 nike

我在 MULTI 事务中封装了一组复杂的 Redis 命令,但事务中的逻辑取决于 Redis 中已有的值。但是事务中的所有读取似乎都返回 nil

这是一个演示问题的示例:

[Dev]> $redis.set("foo", "bar")
=> "OK"
[Dev]> $redis.multi{ $redis.set("foo", "baz") if $redis.get("foo") == "bar" }
=> ["bar"]
[Dev]> $redis.get("foo")
=> "bar"

显然,我希望最后的返回值是 'baz' – 我该如何实现?

最佳答案

你不能,因为所有命令(包括 get)实际上都是在执行时执行的。在这种情况下,get 命令只返回一个 future 的对象,而不是实际值。

有两种方法可以实现这种交易。

使用 WATCH 子句

watch 子句用于防止并发更新。如果变量的值在 watch 和 multi 子句之间更新,则不会应用 multi block 中的命令。由客户再次尝试交易。

loop do
$redis.watch "foo"
val = $redis.get("foo")
if val == "bar" then
res = $redis.multi do |r|
r.set("foo", "baz")
end
break if res
else
$redis.unwatch "foo"
break
end
end

这里的脚本有点复杂,因为 block 的内容可以为空,所以没有简单的方法可以知道交易是否已被取消,或者是否根本没有发生。当多 block 在所有情况下返回结果时通常更容易,除非交易被取消。

使用 Lua 服务器端脚本

使用 Redis 2.6 或更高版本,Lua scripts can be executed on the server .整个脚本的执行是原子的。它可以很容易地用 Ruby 实现:

cmd = <<EOF
if redis.call('get',KEYS[1]) == ARGV[1] then
redis.call('set',KEYS[1],ARGV[2] )
end
EOF
$redis.eval cmd, 1, "foo", "bar", "baz"

这通常比使用 WATCH 子句简单得多。

关于ruby - 如何从 Ruby 中的 MULTI block 中的 Redis 读取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11300958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com