我在使用Datastax java驱动程序组合BatchStatement和Lightweight Transactions时遇到了困难。
请考虑以下事项:
String batch =
"BEGIN BATCH "
+ "Update mykeyspace.mytable set record_version = 102 where id = '" + id + "' if record_version = 101;
" <additional batched statements>
+ "APPLY BATCH";
Row row = session.execute(batch).one();
if (! row.getBool("[applied]")) {
throw new RuntimeException("Optimistic Lock Failure!");
}
此功能按预期运行,并指示我的轻量级事务是否成功以及我的批处理是否已应用。一切都很好。但是,如果我使用BatchStatement尝试相同的事情,我会遇到几个问题:
- 忽略我的轻量级事务“if”子句,并始终应用更新
- “Row”结果为null,因此无法执行最后的row.getBool(“[applied]”)检查。
String update = "Update mykeyspace.mytable set record_version = ? where id = ? if record_version = ?";
PreparedStatement pStmt = getSession().prepare(update);
BatchStatement batch = new BatchStatement();
batch.add(new BoundStatement(pStmt).bind(newVersion, id, oldVersion));
Row row = session.execute(batch).one(); <------ Row is null!
if (! row.getBool("[applied]")) {
throw new RuntimeException("Optimistic Lock Failure!");
}
我这样做错了吗?或者这是数据存储BatchStatement的限制吗?
答案 0 :(得分:4)
我遇到了同样的问题。我昨天开了一张DataStax支持票,收到了以下答案:
目前不支持BATCH中作为PreparedStatements的轻量级事务。这就是您遇到此问题的原因。
立即路线图中没有任何内容可以在Cassandra中包含此功能。
这表明取消PreparedStatement将解决问题。我会亲自尝试,但还没有。
[更新]
我一直在努力解决这个问题。基于之前的反馈,我认为限制是使用PreparedStatement进行条件更新。
我尝试将代码更改为不使用PreparedStatement,但在使用包含RegularStatement而不是PreparedStatement的BatchStatement时仍然无效。
BatchStatement batchStatement = new BatchStatement();
batchStatement.add(conditionalRegularStatement);
session.executeQuery(batchStatement);
他们唯一似乎工作的是使用包含批处理的原始查询字符串执行executeQuery。
session.executeQuery("BEGIN BATCH " + conditionalRegularStatement.getQueryString() + " APPLY BATCH");
答案 1 :(得分:3)
答案 2 :(得分:0)
第二个代码片段对我来说并不合适(没有构造函数带有字符串,或者您错过了准备好的语句)。
您可以尝试以下方式:
String update = "Update mykeyspace.mytable set record_version = ? where id = ? if record_version = ?";
PreparedStatement pStmt = session.prepare(update);
BatchStatement batch = new BatchStatement();
batch.add(pStmt.bind(newVersion, id, recordVersion));
Row row = session.execute(batch).one();
if (! row.getBool("[applied]")) {
throw new RuntimeException("Optimistic Lock Failure!");
}