BoundStatement UpdateTable = new BoundStatement(preparedStatement);
UpdateTable.bind(productId, productname, time);
session.execute(UpdateTable);
我使用以下命令更新cassandra表。有时它会更新,有时则不会。
UPDATE product SET count = count + 1 where productId = ? AND productname = ? AND time = ?;
它永远不会抛出错误。
为什么会这样?
修改
表格结构
CREATE TABLE IF NOT EXISTS product(productId int,productname text,time timestamp , count counter,PRIMARY KEY (productid,productname,time));
答案 0 :(得分:1)
通过查看您的(Java?)代码,我无法确切地知道对象insertUpdateTable
是什么类型。但是bind
方法应该返回一个可以执行的BoundStatement对象。虽然UpdateTable
确实是一个BoundStatement,但我没有看到你实际上是将变量绑定到它。
根据显示的有限数量的代码,我在这里看到两个解决方案:
在bind
内的UpdateTable
上调用session.execute
方法:
session.execute(UpdateTable.bind(productId,productname,time));
将insertUpdateTable.bind
包裹在session.execute
:
session.execute(insertUpdateTable.bind(productId,productname,time));
使用Java驱动程序查看Using Bound Statements上的DataStax文档以获取更多信息。
有时会更新,有时则不会。
如果你发布了你的Cassandra表定义,它可能会对此有所了解。但重要的是要记住Cassandra PRIMARY KEYs是唯一的,INSERT
和UPDATE
s基本相同(INSERT
可以“更新”现有值和{{1可以“插入”新值)。有时,当UPDATE
执行具有相同键值的写入时,UPDATE
似乎不起作用。只是要注意的事情。
另外需要注意的是,UPDATE product SET count = count + 1
只能在两种情况下工作:
count
是一个计数器列。
product
是一个计数器表,仅包含键和计数器列(所有非计数器列必须是PRIMARY KEY的一部分)。
值得注意的是反列underwent a big change/improvement with Cassandra 2.1。如果您需要使用计数器并仍在Cassandra 2.0上,则可能值得升级。
答案 1 :(得分:0)
您说更新有时会起作用,但请注意,如果您使用计数器删除行,则无法在不删除表并重新创建表的情况下再次修改该行。更新似乎无声地失败。有关更多信息,请参阅CASSANDRA-8491
答案 2 :(得分:0)
在高频写入期间我遇到了类似的问题。更新。
随着并发请求数量的增加,最新绑定很可能会覆盖先前绑定的params。因此,不使用单个boundStatement,而是在session.execute
中使用preparedStatement.bind()您可以尝试以下方法。
而不是使用:
UpdateTable.bind(productId, productname, time);
session.execute(UpdateTable);
使用:
session.execute(preparedStatement.bind(productId, productname, time));