This document walks you through how to use RawKV’s CAS (Compare And Swap) API.

In RawKV, compare-and-swap (CAS) is an atomic operation used to avoid data racing in concurrent write requests, which is atomically equivalent to:

  1. prevValue = get(key);
  2. if (prevValue == request.prevValue) {
  3. put(key, request.value);
  4. }
  5. return prevValue;

The atomicity guarantees that the new value is calculated based on up-to-date information. If the value had been updated by another thread at the same time, the write would fail.

Normally, CAS can prevent problems from the concurrent access, but suffers from the ABA problem.

Java

The following example shows how to use CAS API in Java.

  1. import java.util.Optional;
  2. import org.tikv.common.TiConfiguration;
  3. import org.tikv.common.TiSession;
  4. import org.tikv.raw.RawKVClient;
  5. import org.tikv.shade.com.google.protobuf.ByteString;
  6. TiConfiguration conf = TiConfiguration.createRawDefault("127.0.0.1:2379");
  7. // enable AtomicForCAS when using RawKVClient.compareAndSet or RawKVClient.putIfAbsent
  8. conf.setEnableAtomicForCAS(true);
  9. TiSession session = TiSession.create(conf);
  10. RawKVClient client = session.createRawClient();
  11. ByteString key = ByteString.copyFromUtf8("Hello");
  12. ByteString value = ByteString.copyFromUtf8("CAS");
  13. ByteString newValue = ByteString.copyFromUtf8("NewValue");
  14. // put
  15. client.put(key, value);
  16. // get
  17. Optional<ByteString> result = client.get(key);
  18. assert(result.isPresent());
  19. assert("CAS".equals(result.get().toStringUtf8()));
  20. System.out.println(result.get().toStringUtf8());
  21. // cas
  22. client.compareAndSet(key, Optional.of(value), newValue);
  23. // get
  24. result = client.get(key);
  25. assert(result.isPresent());
  26. assert("NewValue".equals(result.get().toStringUtf8()));
  27. System.out.println(result.get().toStringUtf8());
  28. // close
  29. client.close();
  30. session.close();

You must set conf.setEnableAtomicForCAS(true) to ensure linearizability of CAS when using with put, delete, batch_put, or batch_delete.

To guarantee the atomicity of CAS, write operations like put or delete in atomic mode are more expensive.

The code example used in this chapter can be found here.