Skip to content

add SETCAS command#8361

Closed
liexusong wants to merge 2 commits intoredis:unstablefrom
liexusong:unstable
Closed

add SETCAS command#8361
liexusong wants to merge 2 commits intoredis:unstablefrom
liexusong:unstable

Conversation

@liexusong
Copy link
Contributor

Some case we need to use the CAS command to do some work,example: locker

So, I think the CAS command is very useful。

Usage:

setcas key oldvalue newvalue

Compare the oldvalue and set the newvalue, if the key not exists will be successful

@itamarhaber
Copy link
Member

Some relevant historical findings: #1109, #3772 and #5917

@liexusong
Copy link
Contributor Author

Some relevant historical findings: #1109, #3772 and #5917

Thanks, bug some cloud platform no support lua script and redis module, so I think support CAS command is Required。

@soloestoy
Copy link
Contributor

Interesting, it's very useful, and we have already developed a module called TairString to support CAS CAD running in our production environment, and we are preparing to open source on github ^_^

@itamarhaber itamarhaber added class:feature state:major-decision Requires core team consensus labels Jan 20, 2021
@liexusong
Copy link
Contributor Author

Interesting, it's very useful, and we have already developed a module called TairString to support CAS CAD running in our production environment, and we are preparing to open source on github ^_^

Why do not support on master branch?

@madolson
Copy link
Contributor

I would be in favor of adding this, I would probably add it onto SET so you get all the other functionality that comes with it. Like:

SET KEY VALUE [CHECK <old value>]

@ShooterIT
Copy link
Member

AFAIK many people (include me) want this, and del with comparison,. but I remember there are too debates https://groups.google.com/forum/#!topic/redis-db/a4zK2k1Lefo

@sundb
Copy link
Collaborator

sundb commented Jan 21, 2021

When set large string, setcasObjectCompare should be very slow, and the traffic is twice as much.

@liexusong
Copy link
Contributor Author

When set large string, setcasObjectCompare should be very slow, and the traffic is twice as much.

Usually CAS command use small key

@sundb
Copy link
Collaborator

sundb commented Jan 21, 2021

@liexusong you can look at the link of @ShooterIT, where Michal Frackowiak replied.

@itamarhaber
Copy link
Member

@ShooterIT

but I remember there are too debates https://groups.google.com/forum/#!topic/redis-db/a4zK2k1Lefo

I also remembered that one, but couldn't find it - awesome & thank you!

@soloestoy
Copy link
Contributor

Hi all, finally we have open the source code TairString, a module implement CAS CAD and something others interesting commands, please try it.

@yoav-steinberg yoav-steinberg mentioned this pull request Dec 19, 2021
@yoav-steinberg
Copy link
Contributor

Referencing #4258 which can be treated as a special case of SETCAS. We should consider implementing support for it too when/if this ever gets handled.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


liexusong1 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@LiorKogan
Copy link
Member

Internal ticket: RED-156978

minchopaskal added a commit that referenced this pull request Oct 21, 2025
…nd-delete (#14435)

# Description

Add optimistic locking for string objects via compare-and-set and
compare-and-delete mechanism.

## What's changed

Introduction of new DIGEST command for string objects calculated via
XXH3 hash.

Extend SET command with new parameters supporting optimistic locking.
The new value is set only if checks against a given (old) value or a
given string digest pass.

Introduction of new DELEX command to support conditionally deleting a
key. Conditions are also checks against string value or string digest.

## Motivation

For developers who need to to implement a compare-and-set and
compare-and-delete single-key optimistic concurrency control this PR
provides single-command based implementation.

Compare-and-set and compare-and-delete are mostly used for [Optimistic
concurrency
control](https://en.wikipedia.org/wiki/Optimistic_concurrency_control):
a client (1) fetches the value, keeps the old value (or its digest, for
a large string) in memory, (2) manipulates a local copy of the value,
(3) applies the local changes to the server, but only if the server’s
value hasn’t been changed (still equal to the old value).

Note that compare-and-set [can also be
implemented](https://redis.io/docs/latest/develop/using-commands/transactions/#optimistic-locking-using-check-and-set)
with WATCH … MULTI … EXEC and Lua scripts. The new SET optional
arguments and the DELEX command do not enable new functionality,
however, they are much simpler and faster to use for the very common use
case of single-key optimistic concurrency control.

## Related issues and PRs

#12485
#8361
#4258

## Description of the new commands

### DIGEST

```
DIGEST key
```

Get the hash digest of the value stored in key, as an hex string.

Reply:
- Null if key does not exist
- error if key exists but holds a value which is not a string
- (bulk string) the XXH3 digest of the value stored in key, as an hex
string

### SET

```
SET key value [NX | XX | IFEQ match-value | IFNE match-value | IFDEQ match-digest | IFDNE match-digest] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
```

`IFEQ match-value` - Set the key’s value and expiration only if its
current value is equal to match-value. If key doesn’t exist - it won’t
be created.
`IFNE match-value` - Set the key’s value and expiration only if its
current value is not equal to match-value. If key doesn’t exist - it
will be created.
`IFDEQ match-digest` - Set the key’s value and expiration only if the
digest of its current value is equal to match-digest. If key doesn’t
exist - it won’t be created.
`IFDNE match-digest` - Set the key’s value and expiration only if the
digest of its current value is not equal to match-digest. If key doesn’t
exist - it will be created.

Reply update:
- If GET was not specified:
   - Nil reply if either
- the key doesn’t exist and XX/IFEQ/IFDEQ was specified. The key was not
created.
- the key exists, and NX was specified or a specified
IFEQ/IFNE/IFDEQ/IFDNE condition is false. The key was not set.
   - Simple string reply: OK: The key was set.
- If GET was specified, any of the following:
- Nil reply: The key didn't exist before this command (whether the key
was created or not).
- Bulk string reply: The previous value of the key (whether the key was
set or not).

### DELEX

```
DELEX key [IFEQ match-value | IFNE match-value | IFDEQ match-digest | IFDNE match-digest]
```

Conditionally removes the specified key. A key is ignored if it does not
exist.

`IFEQ match-value` - Delete the key only if its value is equal to
match-value
`IFNE match-value` - Delete the key only if its value is not equal to
match-value
`IFDEQ match-digest` - Delete the key only if the digest of its value is
equal to match-digest
`IFDNE match-digest` - Delete the key only if the digest of its value is
not equal to match-digest

Reply: 
- error if key exists but holds a value that is not a string and
IFEQ/IFNE/IFDEQ/IFDNE is specified.
- (integer) 0 if not deleted (the key does not exist or a specified
IFEQ/IFNE/IFDEQ/IFDNE condition is false), or 1 if deleted.

### Notes

Added copy of xxhash repo to deps -
[version](Cyan4973/xxHash@c961fbe)

---------

Co-authored-by: debing.sun <debing.sun@redis.com>
Co-authored-by: Yuan Wang <wangyuancode@163.com>
@sundb
Copy link
Collaborator

sundb commented Oct 28, 2025

Close via #14435

@sundb sundb closed this Oct 28, 2025
@github-project-automation github-project-automation bot moved this from Backlog to Done in Redis Backlog Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

class:feature state:major-decision Requires core team consensus

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

10 participants