- Cassandra 4.1.7 läuft im Docker auf einem Ubuntu-Host, einzelner Knoten
- Java-Client mit Datastax-Treiber 3.11.5, JDK 11.0.25
Code: Select all
public class Main {
public static void main(String[] args) throws Exception {
try (Cluster cluster = connect()) {
Session session = cluster.connect();
session.execute("DROP KEYSPACE IF EXISTS lwt_test");
session.execute("CREATE KEYSPACE lwt_test WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 } AND DURABLE_WRITES = true");
session.execute("CREATE TABLE lwt_test.lwt (key timeuuid, dummy text, value text, PRIMARY KEY(key))");
session.execute("USE lwt_test");
final UUID key = UUIDs.timeBased();
final String dummy = "ABC";
final String value = "DEF";
session.execute("insert into lwt(key, dummy, value) values(?, ?, ?)", key, dummy, value);
final String value2 = "XYZ";
session.execute("update lwt set value=? where key=?", value2, key);
String actualValue = session.execute("select value from lwt where key=?", key).one().getString("value");
if (!value2.equals(actualValue)) {
throw new RuntimeException("Should be " + value + " but was " + actualValue);
}
// (1) uncomment next line to make the problem go away
// Thread.sleep(1000);
ResultSet rs = session.execute("update lwt set value='MUHAHA' where key=? if value=?", key, value2);
if (rs.wasApplied()) {
actualValue = session.execute("select value from lwt where key=?", key).one().getString("value");
if (!"MUHAHA".equals(actualValue)) {
throw new RuntimeException("Should be MUHAHA but was " + actualValue);
}
System.out.println("SUCCESS: actual value is " + actualValue);
}
}
}
private static Cluster connect() {
return Cluster.builder()
.addContactPoints("remote-cluster")
.withPort(9042)
.withQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM))
// (2) uncomment next line to make the problem go away
// .withTimestampGenerator(ServerSideTimestampGenerator.INSTANCE)
.build();
}
}
Code: Select all
Exception in thread "main" java.lang.RuntimeException: Should be MUHAHA but was XYZ
at org.example.Main.main(Main.java:37)
Gleichzeitig funktioniert der gleiche Code unter MacOS ohne Fehler.
Die Problemumgehung besteht darin, entweder zu warten, bevor die Aktualisierung mit LWT ausgeführt wird (1), oder serverseitige Zeitstempel zu verwenden (2), was bei Clustern mit mehreren Knoten zu weiteren Problemen führen könnte laut Diskussion in https://issues.apache.org/jira/browse/CASSANDRA-6178
Ich habe auch verschiedene Versionen von Cassandra (3.11 und 5.0.2) und den Java-Treiber 4.17.0 ausprobiert – den Das Problem besteht in allen Kombinationen weiterhin.
Es sieht aufgrund des unterschiedlichen Ergebnisses unter Windows und MacOS nicht nach dem erwarteten Verhalten aus und es sieht eher nach einem Treiberproblem als nach einem Serverproblem aus selbst.
Gibt es eine Möglichkeit, es ohne „Ruhezustand“ zum Laufen zu bringen, indem der standardmäßige (treiberseitige) Zeitstempelgenerator unter Windows verwendet wird?