无法更新cassandra中的静态列
我有Cassandra(版本2.2.3)数据库的奇怪问题,并使用发送资金功能编写简单应用程序的概念证明时使用静态列。无法更新cassandra中的静态列
我的表是:
CREATE TABLE transactions (
profile text,
timestamp timestamp,
amount text,
balance text,
lock int static,
PRIMARY KEY (profile, timestamp)) WITH CLUSTERING ORDER BY (timestamp ASC);
第一步我添加新的记录
INSERT INTO transactions (profile, timestamp, amount) VALUES ('test_profile', '2015-11-05 15:20:01+0000', '10USD');
然后我想“锁定”当前用户的交易做一些动作与他的平衡。我尝试执行此请求:
UPDATE transactions SET lock = 1 WHERE profile = 'test_profile' IF lock = null;
但作为结果cqlsh我看到
[applied]
-----------
False
我不明白为什么“假”,因为轮廓当前数据是:
profile | timestamp | lock | amount | balance
--------------+--------------------------+------+--------+---------
test_profile | 2015-11-05 15:20:01+0000 | null | 10USD | null
任何想法我做错了什么?
UPDATE
读内纳德Bozic医师的回答后,我改变我的例子来阐明为什么我需要更新条件。完整的代码示例
CREATE TABLE transactions (
profile text,
timestamp timestamp,
amount text,
balance text,
lock int static,
balances map<text,text> static,
PRIMARY KEY (profile, timestamp)
) WITH CLUSTERING ORDER BY (timestamp ASC);
INSERT INTO transactions (profile, timestamp, amount) VALUES ('test_profile', '2015-11-05 15:20:01+0000', '1USD');
INSERT INTO transactions (profile, lock) VALUES ('test_profile', 1) IF NOT EXISTS;
BEGIN BATCH
UPDATE transactions SET balances={'USD':'1USD'} WHERE profile='test_profile';
UPDATE transactions SET balance='1USD' WHERE profile='test_profile' AND timestamp='2015-11-05 15:20:01+0000';
DELETE lock FROM transactions WHERE profile='test_profile';
APPLY BATCH;
如果我尝试再次获得锁我得到
INSERT INTO transactions (profile, lock) VALUES ('test_profile', 1) IF NOT EXISTS;
[applied] | profile | timestamp | balances | lock | amount | balance
-----------+--------------+-----------+-----------------+------+--------+---------
False | test_profile | null | {'USD': '1USD'} | null | null | null
当你INSERT
你不插入lock
场,这意味着这个领域不存在。 CQLSH或DevCenter中的空值表示仅仅是合成糖,使结果看起来像表格数据,但实际上它具有动态键值,并且lock
不存在于键值的映射中。查看数据的thrift representation是有用的,即使它不再用于了解数据如何存储到磁盘。
因此,当UPDATE
被激活时,期望列出现以更新它。在你的情况下,lock
列甚至不存在,所以它不能更新它。这个thread对INSERT
和UPDATE
之间的区别也是很好的阅读。
你有两个解决方案,以使这项工作:
插入空明确
您可以添加lock
到您的插入语句,并将其设置为null(在Cassandra是不同的比从插入排除它因为这样一来就会得到空值,当你排除此列不会在
INSERT INTO transactions (profile, timestamp, amount, lock)
VALUES ('test_profile', '2015-11-05 15:20:01+0000', '10USD', null);
存在使用上插入第二STA tement
既然你是在第二条语句lock
将首次,而不是更新现有的价值,因为它是该分区的静态列,您可以用INSERT IF NOT EXISTS
,而不是做这件事的UPDATE IF
LWT方式(锁就不会存在,所以这将通过第一次失败的所有其他时间,因为锁将有值):
INSERT INTO transactions (profile, lock)
VALUES ('test_profile', 1) IF NOT EXISTS;
请查看我的更新 – greenhost87
由于DE Cassandra中的LETE不是物理删除,而是逻辑删除(在下一次压缩时列值被标记为逻辑删除) - http://docs.datastax.com/en/cql/3.0/cql/cql_using/use_delete.html –
我建议在这里使用值(锁定= 1,不锁定= 0或布尔值或其他)并根据此值切换值。在第一次插入时,将它设置为0,然后使用IF锁定= 0等方式进行条件更新。同时要注意,批量只是全部或全部操作,但它不能保证语句的顺序。 –
可能是相同的问题https://issues.apache.org/jira/browse/CASSANDRA-10532 –
我在'考cassandra 3.0.0-rc2'和它的工作原理...但不能在其他版本中工作... – greenhost87