Henley Wing Chiu
Henley Wing Chiu

Reputation: 22515

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

Upvotes: 3

Views: 2911

Answers (2)

Magnielcz
Magnielcz

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

Itamar Haber
Itamar Haber

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

Related Questions