This page walks you through a simple demonstration of performing compare-and-swap (CAS) in TiKV.
In RawKV, compare-and-swap (CAS) is an atomic instruction to achieve synchronization between multiple threads.
Performing CAS is an atomic equivalent of executing the following code:
prevValue = get(key);
if (prevValue == request.prevValue) {
put(key, request.value);
}
return prevValue;
The atomicity guarantees that the new value is calculated based on the up-to-date information. If the value is updated by another thread at the same time, the write would fail.
Prerequisites
Make sure that you have installed TiUP, jshell, downloaded tikv-client JAR files, and started a TiKV cluster according to TiKV in 5 Minutes.
Verify CAS
To verify whether CAS works, you can take the following steps.
Step 1: Write the code to test CAS
Save the following script to the test_raw_cas.java
file.
import java.util.Optional;
import org.tikv.common.TiConfiguration;
import org.tikv.common.TiSession;
import org.tikv.raw.RawKVClient;
import org.tikv.shade.com.google.protobuf.ByteString;
TiConfiguration conf = TiConfiguration.createRawDefault("127.0.0.1:2379");
// enable AtomicForCAS when using RawKVClient.compareAndSet or RawKVClient.putIfAbsent
conf.setEnableAtomicForCAS(true);
TiSession session = TiSession.create(conf);
RawKVClient client = session.createRawClient();
ByteString key = ByteString.copyFromUtf8("Hello");
ByteString value = ByteString.copyFromUtf8("CAS");
ByteString newValue = ByteString.copyFromUtf8("NewValue");
// put
client.put(key, value);
System.out.println("put key=" + key.toStringUtf8() + " value=" + value.toStringUtf8());
// get
Optional<ByteString> result = client.get(key);
assert(result.isPresent());
assert("CAS".equals(result.get().toStringUtf8()));
System.out.println("get key=" + key.toStringUtf8() + " result=" + result.get().toStringUtf8());
// cas
client.compareAndSet(key, Optional.of(value), newValue);
System.out.println("cas key=" + key.toStringUtf8() + " value=" + value.toStringUtf8() + " newValue=" + newValue.toStringUtf8());
// get
result = client.get(key);
assert(result.isPresent());
assert("NewValue".equals(result.get().toStringUtf8()));
System.out.println("get key=" + key.toStringUtf8() + " result=" + result.get().toStringUtf8());
// close
client.close();
session.close();
Step 2: Run the code
jshell --class-path tikv-client-java.jar:slf4j-api.jar --startup test_raw_cas.java
The example output is as follows:
put key=Hello value=CAS
get key=Hello result=CAS
cas key=Hello value=CAS newValue=NewValue
get key=Hello result=NewValue
As in the example output, after calling compareAndSet
, the value CAS
is replaced by newValue
.
To ensure the linearizability of
CAS
when it is used together withput
,delete
,batch_put
, orbatch_delete
, you must setconf.setEnableAtomicForCAS(true)
.To guarantee the atomicity of CAS, write operations such as
put
ordelete
in atomic mode take more resources.