Nie możesz, ponieważ wszystkie polecenia (w tym get) są faktycznie wykonywane w czasie wykonywania. W tej sytuacji polecenie get zwraca tylko przyszły obiekt, a nie rzeczywistą wartość.
Istnieją dwa sposoby realizacji takiej transakcji.
Korzystanie z klauzuli WATCH
Klauzula watch służy do ochrony przed współbieżnymi aktualizacjami. Jeśli wartość zmiennej jest aktualizowana między klauzulą watch i multi, polecenia w bloku multi nie są stosowane. Od klienta zależy, czy spróbuje wykonać transakcję innym razem.
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
Tutaj skrypt jest nieco skomplikowany, ponieważ zawartość bloku może być pusta, więc nie ma łatwego sposobu, aby dowiedzieć się, czy transakcja została anulowana, czy też w ogóle nie miała miejsca. Generalnie łatwiej jest, gdy multiblok zwraca wyniki we wszystkich przypadkach, z wyjątkiem sytuacji, gdy transakcja jest anulowana.
Korzystanie ze skryptów po stronie serwera Lua
Z Redis 2.6 lub nowszym, skrypty Lua mogą być wykonywane na serwerze. Wykonanie całego skryptu jest atomowe. Można go łatwo zaimplementować w Rubim:
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"
Jest to zwykle znacznie prostsze niż użycie klauzul WATCH.