如何在Cassandra中处理种族状况?

时间:2019-01-14 15:20:50

标签: java spring cassandra race-condition spring-data-cassandra

我正在使用Cassandra db开发一个简单的Spring Boot微服务。

我的服务器中以下Subscription类中的主要实体:

public final class Subscription {

    private String id;

    private String firstUser;

    private String secondUser;

    private String firstUserStatus;

    private String secondUserStatus;

}

我的存储库使用Subscription对象并将其持久化。 但是在坚持之前,我应该检查一些约束条件,主要是不能有另一个具有相同的firstUsersecondUser的订阅。 它可能失败的情况非常简单:

  1. 一个订阅将被保留
  2. 正在验证
  3. 表是否存在另一个订阅 相同的用户
  4. 与相同用户的另一个订阅现在可以保留,并且 使先前的验证失效
  5. 订阅被保留。

解决该问题的正确方法是什么?

值得一提的是:用户的顺序无关紧要。如果要持久保留用户“ 1”和“ 2”的订阅,则必须不存在用户“ 1”和“ 2”或“ 2”和“ 1”的其他订阅。

UPD:考虑@bhspencer的答案,我可以提出另一种情况(我还需要强制状态保持一致):

  1. 一个订阅将与firstUserStatus="ISSUED"secondUserStatus="WAITING_ACTION"保持一致
  2. 正在验证
  3. 表是否存在具有相同用户的另一个订阅
  4. 另一个具有相同ID(用户)以及firstUserStatus="WAITING_ACTION"secondUserStatus="ISSUED"的订阅现在可以保留,并使先前的验证失效
  5. 初始订阅被保留,并覆盖已经存在的初始订阅-> secondUserStatus="ISSUED"丢失

1 个答案:

答案 0 :(得分:2)

使对象的ID为firstUser + secondUser的串联。将id用作确保您的订阅唯一的主键。

由于您的订购要求,您应该首先对firstUser和secondUser进行排序,然后将它们按排序顺序进行连接。这样做意味着generateId(“ 1”,“ 2”)和generateId(“ 2”。“ 1”)都将生成相同的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;
}