You cannot, as all commands (including get) are actually executed at runtime. In this situation, the get command returns only the future object, not the actual value.
There are two ways to implement such a transaction.
Using the WATCH clause
The watch clause is used to protect against simultaneous updates. If the variable value is updated between the watch clause and multi clause, the commands in the multiblock are not applied. The client may complete the transaction at another time.
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
Here the script is a bit complicated because the contents of the block may be empty, so there is no easy way to find out if the transaction was canceled or not at all. It is usually easier when the multiscreen block returns results in all cases, except when the transaction is canceled.
Using Lua Server Scripting
With Redis 2.6 or better, Lua scripts can be executed on the server. The execution of the entire script is atomic. It can be easily implemented 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"
This is usually much simpler than using WATCH clauses.
Didier spezia
source share