【发布时间】:2014-06-25 10:30:51
【问题描述】:
我有一个 cassandra table1:
CREATE TABLE Policy.table1 (
name VARCHAR ,
date TIMESTAMP ,
version_num INT,
PRIMARY KEY (
name
)) WITH caching = 'all'
-- and memtable_flush_period_in_ms = 7200 ;
;
我需要在 tis 表上实现乐观锁定。当我们从 table1 中读取一行时,我们会记住它的 version_num。当我们想要更新这一行时,我们比较当前的 version_num 值和我们记住的值。我们还需要在每次更新时增加 version_num。
问题:
-
我们不能将 version_num 放入 where 子句,这会产生错误:Bad Request: Non PRIMARY KEY version_num found in where 子句:
update table where name = 'abc' and version = 3 我们不能将version_num设置为主键的一部分,因为我们需要更新它的值
- 如果我们索引 version_num,它对更新语句没有帮助,会抛出同样的异常
- 我看到的唯一方法是通过 Java 获取当前 version_num 值,如果预期和实际 version_num 值相同,则执行更新。问题是在这种情况下,我们没有检查 version_num 值和更新行的原子操作。
你看到这个问题的任何解决方案了吗?
【问题讨论】:
-
+1,好问题。挑剔 - 你说“我需要在 tis 表上实现乐观锁定”。但是,这不是一种“需求”,而是一种满足需求的解决方案,即特定用户的需求。 Cassandra 上的乐观锁定可能是在后关系上下文中应用关系模式的一种情况,并且可能存在为用户体验提供相同目的的后关系模式。我很期待看到您是否能得到一些适合 Cassandra 的好答案。
-
所以,这里有一个想法。如果每次更改只是一个新行怎么办。版本号不存储在行中,而只是 name = 'blah' 的行数?可能会使用大量磁盘,具体取决于您拥有多少行以及每行更新多少次。
-
您实际上可以将计数存储在(单独的)计数器表中。所以,写到名单上,撞上柜台。如果两次写入,计数器仍然有正确的值,因为计数器被撞了两次。
-
鉴于此,您只需要决定如何处理数据行的历史值。你需要它们吗?然后保留日志。还是你覆盖它们?这将意味着更少的磁盘,并且在日期上“最后写入获胜”。
-
您能否将您的解决方案作为答案而不是问题的一部分?