首页 文章

具有轻量级事务的Cassandra Datastax BatchStatement

提问于
浏览
1

我在使用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的限制?

3 回答

  • 3

    我遇到了同样的问题 . 我昨天开了一张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");
    
  • 2

    更新:

    此问题已在_1565219中解决,该问题已在C * 2.0.9中修复 .

    最新的DataStax Enterprise现在是2.0.11 . 如果您看到此问题==>升级!

  • 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!");
    }
    

相关问题