Você não pode, pois todos os comandos (incluindo get) são realmente executados em tempo de execução. Nessa situação, o comando get retorna apenas um objeto futuro, não o valor real.
Existem duas maneiras de implementar tal transação.
Usando uma cláusula WATCH
A cláusula watch é usada para proteger contra atualizações simultâneas. Se o valor da variável for atualizado entre a cláusula watch e multi, os comandos no bloco multi não serão aplicados. Cabe ao cliente tentar a transação outra vez.
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
Aqui o script é um pouco complexo porque o conteúdo do bloco pode estar vazio, então não há uma maneira fácil de saber se a transação foi cancelada ou se não ocorreu. Geralmente é mais fácil quando o multiblock retorna resultados em todos os casos, exceto se a transação for cancelada.
Usando scripts do lado do servidor Lua
Com o Redis 2.6 ou superior, os scripts Lua podem ser executados no servidor. A execução de todo o script é atômica. Ele pode ser facilmente implementado em 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"
Isso geralmente é muito mais simples do que usar cláusulas WATCH.