Dat kan niet, aangezien alle commando's (inclusief get) daadwerkelijk op exec-tijd worden uitgevoerd. In deze situatie retourneert het get-commando alleen een toekomstig object, niet de werkelijke waarde.
Er zijn twee manieren om een dergelijke transactie te implementeren.
Een WATCH-clausule gebruiken
De watch-clausule wordt gebruikt om te beschermen tegen gelijktijdige updates. Als de waarde van de variabele tussen de watch- en multi-clausule wordt bijgewerkt, worden de opdrachten in het multi-blok niet toegepast. Het is aan de klant om de transactie een andere keer te proberen.
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 is het script een beetje ingewikkeld omdat de inhoud van het blok leeg kan zijn, dus er is geen gemakkelijke manier om te weten of de transactie is geannuleerd of helemaal niet heeft plaatsgevonden. Het is over het algemeen gemakkelijker wanneer het multiblok in alle gevallen resultaten oplevert, behalve als de transactie wordt geannuleerd.
Lua server-side scripting gebruiken
Met Redis 2.6 of beter kunnen Lua-scripts op de server worden uitgevoerd. De uitvoering van het hele script is atomair. Het kan eenvoudig worden geïmplementeerd in 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"
Dit is doorgaans veel eenvoudiger dan het gebruik van WATCH-clausules.