3
votes

I want to run a HSET command but only if the key exists. Similar to HSETNX except exists instead of not exists

I've read about maybe using WATCH or something but so far I can't really figure it out. I would appreciate a nudge in the right direction. The only thing I see is this but I don't see how this works considering these aren't even valid redis commands.

HSET if key exist

Also, after reading about WATCH that concerns me because I don't want to abort the transaction if another request comes it.

I'm basically trying to HGETALL and immediately after issue a second command for HSET, saying that it has been read a single time.

After that, I want all subsequent requests to know that it's already been read.

The problem is, when I call HSET on a key that doesn't exist, instead of just failing it creates a new entry in the redis database, which I don't want. I only want it to update records if it exists without having to check if it exists first

According to this, that method won't work anyway for high contention (there will be lots of requests to the key)

https://github.com/antirez/redis/issues/441

It says I could use scripting somehow but I'm not sure

1

1 Answers

4
votes

Yes. You can execute a lua script in Redis by running EVAL command. All the commands after the EVAL will be blocked until the EVAL has completed, since Redis is a single-threaded server.

The documentation says:

EVAL and EVALSHA are used to evaluate scripts using the Lua interpreter built into Redis starting from version 2.6.0.

So, it's easy to implement a simple HSETX command,just run the lua script below: eval "if redis.call('exists',KEYS[1]) == 1 then redis.call('hset', KEYS[1], ARGV[1], 0) end" 1 test_key test_field