How to handle Race Condition in Cassandra?

Viewed 339

I am developing a simple Spring Boot microservice with Cassandra db.

The main entity in my server in Subscription class below:

public final class Subscription {

    private String id;

    private String firstUser;

    private String secondUser;

    private String firstUserStatus;

    private String secondUserStatus;

}

My repository consumes Subscription object and persists it. But before persisting, I should check for some constraints and the main is that there mustn't be another subscription with the same firstUser and secondUser. The case when it can fail is pretty simple:

  1. one subscription is going to be persisted
  2. table is being verified for the existence of another subscription with the same users
  3. another subscription with the same users could be persisted now and make the previous verification stale
  4. subscription is being persisted.

What is the proper way to resolve it?

Worth mentioning: the order of users doesn't matter. If subscription with users "1" and "2" is going to be persisted no other subscription with users "1" and "2" or "2" and "1" must exist.

UPD: considering @bhspencer answer, I could propose another case (I need also force statuses to be consistent):

  1. one subscription is going to be persisted with firstUserStatus="ISSUED" and secondUserStatus="WAITING_ACTION"
  2. table is being verified for the existence of another subscription with the same users
  3. another subscription with the same id (users) and firstUserStatus="WAITING_ACTION" and secondUserStatus="ISSUED" could be persisted now and make the previous verification stale
  4. initial subscription is being persisted and overrides the already existed one -> secondUserStatus="ISSUED" is lost
1 Answers

Make the id of the object a concatenation of firstUser + secondUser. Make id the primary key that will ensure your subscriptions are unique.

Because of your ordering requirement you should sort the firstUser and secondUser first and concatenate them in sort order. Doing this means generateId("1", "2") and generateId("2". "1") would both generate the same id "1-2".

public String generateId(String firstUser, String secondUser) {
  List<String> ids = new ArrayList<>();
  ids.add(firstUser);
  ids.add(secondUser);
  Collections.sort(ids);
  String result = ids.get(0) + "-" + ids.get(1);
  return result;
}
Related