Reputation: 22515
How do I call .incr on a key and have it increment ONLY if the resulting number is < than a certain number without having to call .get beforehand?
The reason why is calling .get beforehand is problematic is because if I have multiple threads. There could possibly be 100 threads that have executed the first line below, they all get the value "0" and as a result, all increment. A race condition, if you will.
currentVal = $redis.get('key') #all threads could be done executing this but not yet the below if condition.
if(currentVal < 3)
$redis.incr('key') #1
end
Upvotes: 3
Views: 2911
Reputation: 31
I took the idea for lua script from Itamar Haber, improve it so it works, and added return values to know what happened on client side.
local r=redis.call('GET', KEYS[1])
if not r or tonumber(r) < tonumber(ARGV[1])
then
redis.call('INCR', KEYS[1])
return 1
else
return 0
end
Upvotes: 0
Reputation: 49942
You can either use WATCH
/MULTI
/EXEC
semantics for optimistic locking, or compose a Lua such as this one (not tested):
local r=redis.call('GET', KEYS[1])
if r < ARGV[1] then
redis.call('INCR', KEYS[1])
end
Upvotes: 1