Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SETX/MSETX/HSETX command #441

Closed
Observer13 opened this issue Apr 8, 2012 · 3 comments
Closed

SETX/MSETX/HSETX command #441

Observer13 opened this issue Apr 8, 2012 · 3 comments

Comments

@Observer13
Copy link

Hello,

We'd like Redis to implement a SETX/MSETX/HSETX command so we can find and modify existing key/value, currently things can be done using EXIST followed by a SET, but that solution is vulnerable under race conditions.

MongoDB has the findAndModify command that find and modify values atomically, until Redis implement something similar we can't migrate some of our stack to Redis.

Someone wrote a patch on this a year ago:
https://github.com/4z3/redis/compare/MSETX%2BSETX

It'd be greatly appreciated if the Redis team can take a look.

Thank you.

@sripathikrishnan
Copy link

Redis already has support for your use case. Take a look at Redis' support for transactions. Specifically, the watch and exec commands. See the section "Optimistic locking using check-and-set" on this page - http://redis.io/topics/transactions

@Observer13
Copy link
Author

What happens when Redis WATCH something that doesn't exist then it gets created/changed by multiple clients half way?

According to the manual (http://redis.io/commands/watch), WATCH always return OK, under race condition we can end up with 100 clients WATCHing something that doesn't exist at the same moment, not knowing if the key is there or not. Then, during the WATCH, all the clients must run EXIST to see if the key exists (to find and modify), when some of them get the YES then they all run SET at the same time.

Then, according to the manual, "If at least one watched key is modified before the EXEC command, the whole transaction aborts", so WATCH will only allow the fastest client to run SET, then terminate all the other just-a-little-slower clients that are also running WATCH and SET.

Terminating clients when a value is changed isn't what we're looking for. We want to allow multiple updates only on a key that exists, atomically return false if the key doesn't exist, and not terminating other clients that is also updating the same key. This can all be executed in one command if SETX is implemented.

@antirez
Copy link
Contributor

antirez commented Apr 8, 2012

WATCH is the good solution if you don't have too much contention in the same key at the same time, otherwise what you want is Redis scripting that is going to be available as Redis 2.6 RC1 in a few days.

Closing because scripting perfectly solves this use case with a simple script. Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants