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
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions