以下问题需要使用DataStax中的Java驱动程序对Cassandra中的轻量级事务进行推理/解释。
我想要一个插入操作,只有在数据不存在时才会成功。为了实现这个CQL,使用了IF
子句。这是代码:
public boolean insert( String key, String value )
{
String cql = QueryBuilder.insertInto( KEYSPACE, TABLE_NAME )
.ifNotExists()
.value( COL_1, QueryBuilder.bindMarker() )
.value( COL_2, QueryBuilder.bindMarker() )
.toString();
Row row = session.execute( cql, key, value ).one();
return row.getBool( 0 ); // this is equivalent to row.getBool("applied")
}
public void delete( String key )
{
String cql = QueryBuilder.delete().from( KEYSPACE, TABLE_NAME )
.where( QueryBuilder.eq( COL_1, QueryBuilder.bindMarker() ) )
.toString();
session.execute( cql, key );
}
In insert
method code, applied
column is used to check the result of conditional queries
请注意,COL_1
是主键,代码是从工作环境中获取的简化版本。现在人们会期望以下行为重复调用此三元组:
delete("key");
insert("key", "value"); // returns true
insert("key", "value"); // returns false
是的,这是预期的结果,而且正是如此。 但并非总是如此!我们的单元测试有时由于某些未知原因而失败 - 第二次插入返回true。我对此很着迷,最后找到了解决方案 - 在删除操作中添加IF
子句会在重复调用时删除所有意外结果。
现在我感兴趣的是这背后的原因是什么。为什么使用insert
子句在IF
中使用的CAS(比较和设置)技术不够用?为什么IF
操作中应该有delete
子句?