sql >> Base de Datos >  >> NoSQL >> Redis

¿Cómo puedo leer desde Redis dentro de un bloque MULTI en Ruby?

No puede, ya que todos los comandos (incluido get) se ejecutan en tiempo de ejecución. En esta situación, el comando get solo devuelve un objeto futuro, no el valor real.

Hay dos formas de implementar dicha transacción.

Uso de una cláusula WATCH

La cláusula de vigilancia se utiliza para proteger contra actualizaciones simultáneas. Si el valor de la variable se actualiza entre la cláusula watch y multi, los comandos del bloque multi no se aplican. Depende del cliente intentar la transacción en otro momento.

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

Aquí, el script es un poco complejo porque el contenido del bloque puede estar vacío, por lo que no hay una manera fácil de saber si la transacción se canceló o si no se llevó a cabo. Por lo general, es más fácil cuando el bloque múltiple devuelve resultados en todos los casos, excepto si se cancela la transacción.

Uso de secuencias de comandos del lado del servidor Lua

Con Redis 2.6 o superior, los scripts de Lua se pueden ejecutar en el servidor. La ejecución de todo el script es atómica. Se puede implementar fácilmente en 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"

Esto suele ser mucho más simple que usar cláusulas WATCH.