'Redis increment only if < certain number?

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


Solution 1:[1]

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

Solution 2:[2]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Itamar Haber
Solution 2 Magnielcz