3

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
2
  • I've tried to do this before and the only way that seemed possible was with a Lua script. You could petition for a command like INCRBYTOMAX. Commented Dec 5, 2016 at 19:30
  • if currentVal is hard coded, couldn't you do the check after the incr then decr? Commented Dec 5, 2016 at 19:51

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.