如何确保数据库

时间:2017-10-16 21:40:39

标签: java spring-boot concurrency cassandra

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

在id生成之后,我检查db是否有任何具有相同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的实体时才插入实体?

2 个答案:

答案 0 :(得分:7)

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

如果需要,还可以在查询中使用带有@"\s"子句的轻量级事务。

IF NOT EXISTS

如果该行尚不存在,则仅应用该突变。查询将返回一个INSERT INTO keyspace_name.table_name ( identifier, column_name...) VALUES ( value, value ... ) IF NOT EXISTS 字段,告诉您它是否成功。如果另一个插入相同的东西,只有一个可以工作。

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

这会慢一些因为它使用paxos,它会在你的集群周围完成多次跳跃。

答案 1 :(得分: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")
}