Sie können dies nicht, da alle Befehle (einschließlich get) tatsächlich zur Ausführungszeit ausgeführt werden. In dieser Situation gibt der get-Befehl nur ein zukünftiges Objekt zurück, nicht den tatsächlichen Wert.
Es gibt zwei Möglichkeiten, eine solche Transaktion zu implementieren.
Eine WATCH-Klausel verwenden
Die Überwachungsklausel dient zum Schutz vor gleichzeitigen Aktualisierungen. Wenn der Wert der Variablen zwischen der Überwachungs- und der Multi-Klausel aktualisiert wird, werden die Befehle im Multi-Block nicht angewendet. Es obliegt dem Client, die Transaktion ein weiteres Mal zu versuchen.
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
Hier ist das Skript etwas komplex, da der Inhalt des Blocks leer sein kann, sodass es keine einfache Möglichkeit gibt, festzustellen, ob die Transaktion abgebrochen wurde oder ob sie überhaupt nicht stattgefunden hat. Im Allgemeinen ist es einfacher, wenn der Multiblock in allen Fällen Ergebnisse zurückgibt, außer wenn die Transaktion abgebrochen wird.
Serverseitiges Lua-Scripting verwenden
Ab Redis 2.6 können Lua-Skripte auf dem Server ausgeführt werden. Die Ausführung des gesamten Skripts ist atomar. Es kann einfach in Ruby implementiert werden:
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"
Dies ist normalerweise viel einfacher als die Verwendung von WATCH-Klauseln.