Не можете, тъй като всички команди (включително get) всъщност се изпълняват по време на exec. В тази ситуация командата get връща само бъдещ обект, а не действителната стойност.
Има два начина за реализиране на такава транзакция.
Използване на клауза WATCH
Клаузата за часовник се използва за защита срещу едновременни актуализации. Ако стойността на променливата се актуализира между часовника и мулти клаузата, тогава командите в мултиблока не се прилагат. От клиента зависи да опита транзакцията друг път.
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
Тук скриптът е малко сложен, тъй като съдържанието на блока може да е празно, така че няма лесен начин да разберете дали транзакцията е била отменена, или изобщо не се е състояла. По принцип е по-лесно, когато мултиблокът връща резултати във всички случаи, освен ако транзакцията е анулирана.
Използване на Lua скриптове от страна на сървъра
С Redis 2.6 или по-нова версия, 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.