2017-10-16 41 views
0

我想为实体生成唯一的ID并将实体存储在Cassandra数据库中(仅当具有生成的ID的实体已不存在时)。如何确保在数据库中不存在生成的ID

ID生成后,我检查数据库是否有任何具有相同ID的实体。如果不是,则该实体被保存。从为MyService类的示例代码:

synchronized (MyService.class) { 
    do { 
     id = generateId(); 
    } while (myDao.find(id) != null); 
    sampleObject.setId(id); 
    myDao.create(sampleObject); 
} 

在MyDao拯救实体我使用:

cassandraOperations.insert(sampleObject); 

什么是要确保已生成的ID不存在数据库中的最佳做法是什么?我觉得这个同步块并不是最有效的解决方案。 或者,也许有其他方式可以确保只有在数据库中没有相同ID的实体时才插入实体?

+0

检查[此](https://stackoverflow.com/questions/3935915/how-to-create-auto-increment-ids- in-cassandra) – Russiancold

+0

你是否使用uuid作为id?如果是这样,碰撞概率等于0.所以你甚至不需要检查存在 – rvit34

+0

在我的情况下,id是一个字母数字字符串。即使使用UUID,碰撞适应性也非常低。 –

回答

6

类型1 uuids(timeuuid)保证每毫秒(每个主机)创建少于10k uuids的冲突。所以这是最简单的解决方案,不会影响吞吐量或延迟。如果使用类型4的随机uuid(uuid类型),碰撞的可能性小于从数据中心下面喷出的超级火山,但它不提供timeuuid的保证。

如果您想要,还可以在查询中使用轻量级事务处理和IF NOT EXISTS子句。

INSERT INTO keyspace_name.table_name 
    (identifier, column_name...) 
    VALUES (value, value ...) IF NOT EXISTS 

这将只适用于突变,如果该行尚不存在。该查询将返回一个applied字段,告诉您它是否成功。如果另一个插入相同的东西只有一个会工作。

https://docs.datastax.com/en/cql/3.1/cql/cql_reference/insert_r.html#reference_ds_gp2_1jp_xj__if-not-exists

这会慢一些,因为它使用的Paxos,这需要在你的集群多跳完成。

0

UUID是安全的解决方案,但有时id不是很独特。 例如SSN。 要解决它Cassandra支持轻量级交易。 https://docs.datastax.com/en/cql/3.3/cql/cql_using/useInsertLWT.html

在应用方面没有同步是必需的。 Cassandra结果集将返回应用如果记录被写入,则为true。
函数写:

ResultSet insertIfNotExists(String Id) { 
    String cql = QueryBuilder.insertInto("table_name") 
      .value("id", Id) 
      .ifNotExists() 

    return cassandraOperations.query(cql); 
} 

用法:

ResultSet rs = insertIfNotExists("abc123") 
if (rs.wasApplied()) { 
    log.info("success") 
} 
相关问题