2015-11-05 40 views
2

我有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 
+0

可能是相同的問題https://issues.apache.org/jira/browse/CASSANDRA-10532 –

+0

我在'考cassandra 3.0.0-rc2'和它的工作原理...但不能在其他版本中工作... – greenhost87

回答

1

當你INSERT你不插入lock場,這意味着這個領域不存在。 CQLSH或DevCenter中的空值表示僅僅是合成糖,使結果看起來像表格數據,但實際上它具有動態鍵值,並且lock不存在於鍵值的映射中。查看數據的thrift representation是有用的,即使它不再用於瞭解數據如何存儲到磁盤。

因此,當UPDATE被激活時,期望列出現以更新它。在你的情況下,lock列甚至不存在,所以它不能更新它。這個threadINSERTUPDATE之間的區別也是很好的閱讀。

你有兩個解決方案,以使這項工作:

插入空明確

您可以添加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; 
+0

請查看我的更新 – greenhost87

+0

由於DE Cassandra中的LETE不是物理刪除,而是邏輯刪除(在下一次壓縮時列值被標記爲邏輯刪除) - http://docs.datastax.com/en/cql/3.0/cql/cql_using/use_delete.html –

+0

我建議在這裏使用值(鎖定= 1,不鎖定= 0或布爾值或其他)並根據此值切換值。在第一次插入時,將它設置爲0,然後使用IF鎖定= 0等方式進行條件更新。同時要注意,批量只是全部或全部操作,但它不能保證語句的順序。 –