我有以下代码:
def main(args: Array[String]): Unit = {
val cluster = Cluster.builder()
.addContactPoint("localhost")
.withPort(9042)
.build()
val session = cluster.connect()
try {
session.execute(s"CREATE KEYSPACE demoks WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}")
} catch {
case _: AlreadyExistsException =>
}
session.execute(s"USE demoks")
session.execute("DROP table IF EXISTS demo")
session.execute( """
| CREATE TABLE IF NOT EXISTS demo (
| id text,
| data1 map<text, text>,
| data2 map<text, text>,
| PRIMARY KEY (id)
| ) WITH
| compaction = {'class': 'LeveledCompactionStrategy'}
| AND
| compression = { 'sstable_compression' : 'SnappyCompressor' };
""".stripMargin).one()
val p1 = session.prepare("UPDATE demo SET data1[?]=?, data2[?] = ? WHERE id=?")
val p3 = session.prepare("INSERT INTO demo (id,data1) VALUES (?,?) IF NOT EXISTS")
import scala.collection.JavaConverters._
val id2 = "id2-"+System.nanoTime()
session.execute(p3.bind(id2, Map("key" -> "value1-q1").asJava))
session.execute(p1.bind("key", "value1-q2", "key", "value2-q2", id2))
System.exit(0)
}
执行此代码段之后,我只是在select * from demo;
中执行cqlsh
:
通常结果是正确的和预期的:
cqlsh:demoks> select * from demo;
id | data1 | data2
--------------------+----------------------+----------------------
id2-61510117409472 | {'key': 'value1-q2'} | {'key': 'value2-q2'}
(1 rows)
但有时可能会有所不同。看起来查询已重新排序且IF NOT EXISTS
未触发:
cqlsh:demoks> select * from demo;
id | data1 | data2
--------------------+----------------------+----------------------
id2-61522373234949 | {'key': 'value1-q1'} | {'key': 'value2-q2'}
(1 rows)
有人可以解释一下这种行为吗?
这是Cassandra 3.7在Windows机器上的docker中运行。我无法在同一台计算机和所有其他计算机上的Linux或Mac下重现此行为。我尝试了docker和bare安装。而且,即使在同一台机器上进行裸装也无法重现。
答案 0 :(得分:0)
基本上不保证您提供的insert,upsert语句将如何在群集中结束。大多数情况下,您将获得您期望的行为,但并非总是如此。这取决于一些因素,你所达到的协调员是什么,那里的时间是什么。
您有两个选项,使用“使用时间戳”自行设置您生成的语句的时间,或者您可以使用批处理以保证语句的执行顺序:
// your code
Batch batch = QueryBuilder.unloggedBatch()
batch.add(binded p3)
batch.add(binded p1)
// now execute the batch
session.execute(batch)