Du kan inte, eftersom alla kommandon (inklusive get) faktiskt exekveras vid exec-tid. I den här situationen returnerar get-kommandot bara ett framtida objekt, inte det faktiska värdet.
Det finns två sätt att implementera en sådan transaktion.
Använda en WATCH-sats
Watch-paragrafen används för att skydda mot samtidiga uppdateringar. Om värdet på variabeln uppdateras mellan klockan och multisatsen, tillämpas inte kommandona i multiblocket. Det är upp till kunden att försöka göra transaktionen en annan gång.
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
Här är skriptet lite komplext eftersom innehållet i blocket kan vara tomt, så det finns inget enkelt sätt att veta om transaktionen har avbrutits, eller om den inte ägde rum alls. Det är i allmänhet lättare när multiblocket returnerar resultat i alla fall utom om transaktionen avbryts.
Använda skript på serversidan på Lua
Med Redis 2.6 eller bättre kan Lua-skript köras på servern. Utförandet av hela manuset är atomärt. Det kan enkelt implementeras i 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"
Detta är vanligtvis mycket enklare än att använda WATCH-satser.