validar update tiempo registros registro mismo insertar guardar existencia existe ejecutar duplicate duplicados datos antes actualizar cassandra

cassandra - update - C*puede perder una actualización después de INSERTAR SI NO EXISTE



on duplicate key update (1)

Tengo el siguiente código:

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) }

Después de la ejecución de este fragmento, solo estoy select * from demo; en cqlsh :

Por lo general, el resultado es correcto y esperado:

cqlsh:demoks> select * from demo; id | data1 | data2 --------------------+----------------------+---------------------- id2-61510117409472 | {''key'': ''value1-q2''} | {''key'': ''value2-q2''} (1 rows)

Pero a veces puede ser diferente. Parece que las consultas se han reordenado y IF NOT EXISTS no se activó:

cqlsh:demoks> select * from demo; id | data1 | data2 --------------------+----------------------+---------------------- id2-61522373234949 | {''key'': ''value1-q1''} | {''key'': ''value2-q2''} (1 rows)

¿Alguien podría explicarme este comportamiento?

Es Cassandra 3.7 corriendo en acoplador en la máquina de Windows. No puedo reproducir este comportamiento en Linux ni Mac en la misma máquina y todas las demás máquinas. Probé las instalaciones de Docker y bare. Además, no puedo reproducir esto incluso con una instalación simple en la misma máquina.


Básicamente, no hay garantías de cómo las inserciones y resúmenes que proporcione terminarán en el clúster. La mayoría de las veces obtendrá el comportamiento que espera, pero no siempre. Esto depende de algunos factores, ¿cuál es el coordinador al que se dirige, cuál es el tiempo allí?

Tiene dos opciones, establecer la hora usted mismo en las declaraciones que produce utilizando "using timestamp" o puede usar lotes para garantizar el orden de ejecución de sus declaraciones:

// your code Batch batch = QueryBuilder.unloggedBatch() batch.add(binded p3) batch.add(binded p1) // now execute the batch session.execute(batch)