Skip to content

Add support for Batch-level QueryOptions #1192

@wtetsu

Description

@wtetsu

Hello,
I noticed consistencyLevel cannot be set when using batchOps.

  • spring-data-cassandra 3.2.2 and 3.3.0
  • Cassandra 4.0.1 (3 nodes, replication factor:2)

For example, try executing this code that uses batchOps.

Right after this batch process finished, run a query(ONE) to read the deleted data(*1).
Even though ALL is specified in queries in batchOps, the read query sometimes returns the data that was deleted a while ago.

In a few seconds, the same read request always returns empty.
It looks like "ALL" for writing doesn't work.

cassandraTemplate.batchOps()
    .insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
    .delete(..., DeleteOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build()) // (*1)
    .insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
    .execute();

Next, I tried running this code that set ConsistencyLevel.ALL via BatchStatementBuilder.
it worked as expected.
Queries to read the deleted data(*1) never find data even if right after this batch process finished.

var batchOperations = cassandraTemplate.batchOps();
BatchStatementBuilder batch = (BatchStatementBuilder) getField(batchOperations, "batch");
batch.setConsistencyLevel(ConsistencyLevel.ALL);

batchOperations.insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
               .delete(..., DeleteOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build()) // (*1)
               .insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
               .execute();


//private static Object getField(Object obj, String fieldName) {
//  Field privateStringField;
//  try {
//    privateStringField = obj.getClass().getDeclaredField(fieldName);
//    privateStringField.setAccessible(true);
//    return privateStringField.get(obj);
//  } catch (NoSuchFieldException | IllegalAccessException e) {
//    throw new RuntimeException("Failed to getField", e);
//  }
//}

However, the code above accesses the private "batch" field, so I don't think this is "legal" code.

Although StatementBuilder in DataStax Java Driver has public setConsistencyLevel, I cannot call it via Spring Data. Is there any reason it is not exposed to Spring Data users?


Another trial is here.
wtetsu@d806d32

I tried to implement batchOps that can accept ConsistencyLevel.
It worked as expected.

cassandraTemplate.batchOps(ConsistencyLevel.ALL)
    .insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
    .delete(..., DeleteOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build()) // (*1)
    .insert(..., InsertOptions.builder().consistencyLevel(ConsistencyLevel.ALL).build())
    .execute();

Here are my questions:

  • Is there a formal way to specify consistencyLevel when using batchOps?
  • If no, is it possible to expand batchOps features in order to realize it?

Thank you.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions