すべてのコマンド(getを含む)は実際に実行時に実行されるため、実行できません。この場合、getコマンドは実際の値ではなく、将来のオブジェクトのみを返します。
このようなトランザクションを実装するには2通りの方法があります。
時計句が同時更新から保護するために使用されているWATCH句
を使用します。変数の値がwatchとmulti句の間で更新された場合、マルチブロック内のコマンドは適用されません。別の時間にトランザクションを試行するのはクライアントの責任です。
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
ここでブロックの内容を空にすることができますので、スクリプトは少し複雑なので、トランザクションはそれがすべてで行われていなかったかどうかをキャンセル、またはされているかどうかを知るための簡単な方法はありません。一般に、マルチブロックがトランザクションがキャンセルされた場合を除いて、すべてのケースで結果を返す方が簡単です。 Redisの2.6またはより良いではLuaのサーバーサイドスクリプト
を使用して
、Luaのスクリプトはサーバー上で実行することができます。スクリプト全体の実行はアトミックです。それは簡単に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句を使用するよりもはるかに簡単です。
私はあなたがそれをすることができないのですか? –