scottstots
scottstots

Reputation: 193

Sequential batch queries in Cassandra

I have two queries which I wish to execute as a batch to maintain atomicity. The first query is a delete query and the second query is an insert query, both operating on the same table. While it is important for me to ensure atomicity, it is also crucial to maintain the order of the queries (since I do not want to delete the recently inserted row if in case both queries are executed simultaneously and the ordering gets messed up). Thus, I am using the USING TIMESTAMP keyword to define a client-supplied timestamp to achieve the particular order.

My problem is that when I try executing the batch query containing USING TIMESTAMP to provide an order of execution, some of my tests fail on it while other pass. On the other hand, when I completely remove the batch statement and try to execute the two queries sequentially, they all pass. Hence, I believe that strict order of query execution is not being maintained even after using the TIMESTAMP value.

There are two ways I tried to execute my query in Java.

WAY #1

final Session cassandraSession = CassandraSessionManager.getSession();
Batch batch = QueryBuilder.batch();

Delete.Where delete = QueryBuilder.delete().from(CassandraMetadata.KeySpace,CassandraMetadata.Tables.AUTHOPDATA.toString())
                     .using(timestamp(System.nanoTime()))
                     .where(QueryBuilder.eq(CassandraMetadata.AuthOpDataColumns.ECID.toString(), ecId));
batch.add(delete);

Insert insertAuthOp = QueryBuilder.insertInto(CassandraMetadata.KeySpace, CassandraMetadata.Tables.AUTHOPDATA.toString())
                    .using(timestamp(System.nanoTime()))
                    .value(CassandraMetadata.AuthOpDataColumns.ECID.toString(), ecId)
                    .value(CassandraMetadata.AuthOpDataColumns.OPERATION.toString(), operation)
                    .value(CassandraMetadata.AuthOpDataColumns.STATUS.toString(), status);

batch.add(insertAuthOp);
batch.setConsistencyLevel(DbProps.CassandraWriteConsistencyLevel.getValue());
cassandraSession.execute(batch);

WAY #2

final Session cassandraSession = CassandraSessionManager.getSession();
Batch batch = QueryBuilder.batch();

Delete.Where delete = QueryBuilder.delete().from(CassandraMetadata.KeySpace,CassandraMetadata.Tables.AUTHOPDATA.toString())
                     .using(timestamp(1L))
                     .where(QueryBuilder.eq(CassandraMetadata.AuthOpDataColumns.ECID.toString(), ecId));
batch.add(delete);

Insert insertAuthOp = QueryBuilder.insertInto(CassandraMetadata.KeySpace, CassandraMetadata.Tables.AUTHOPDATA.toString())
                    .using(timestamp(2L))
                    .value(CassandraMetadata.AuthOpDataColumns.ECID.toString(), ecId)
                    .value(CassandraMetadata.AuthOpDataColumns.OPERATION.toString(), operation)
                    .value(CassandraMetadata.AuthOpDataColumns.STATUS.toString(), status);

batch.add(insertAuthOp);
batch.setConsistencyLevel(DbProps.CassandraWriteConsistencyLevel.getValue());
cassandraSession.execute(batch);

The output is same for both the executions. The same tests fail when I execute both the queries because they do not find the expected data in the table (while other tests using the same method pass). I wanted to know if there is a way to implement strict sequentiality in executing batch queries, and if this is the only method to ensure that, is there something I might be missing in my execution.

Upvotes: 2

Views: 306

Answers (0)

Related Questions