【问题标题】:Cassandra Optimistic LockingCassandra 乐观锁定
【发布时间】: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。

问题:

  1. 我们不能将 version_num 放入 where 子句,这会产生错误:Bad Request: Non PRIMARY KEY version_num found in where 子句:

     update table where name = 'abc' and version = 3
    
  2. 我们不能将version_num设置为主键的一部分,因为我们需要更新它的值

  3. 如果我们索引 version_num,它对更新语句没有帮助,会抛出同样的异常
  4. 我看到的唯一方法是通过 Java 获取当前 version_num 值,如果预期和实际 version_num 值相同,则执行更新。问题是在这种情况下,我们没有检查 version_num 值和更新行的原子操作。

你看到这个问题的任何解决方案了吗?

【问题讨论】:

  • +1,好问题。挑剔 - 你说“我需要在 tis 表上实现乐观锁定”。但是,这不是一种“需求”,而是一种满足需求的解决方案,即特定用户的需求。 Cassandra 上的乐观锁定可能是在后关系上下文中应用关系模式的一种情况,并且可能存在为用户体验提供相同目的的后关系模式。我很期待看到您是否能得到一些适合 Cassandra 的好答案。
  • 所以,这里有一个想法。如果每次更改只是一个新行怎么办。版本号不存储在行中,而只是 name = 'blah' 的行数?可能会使用大量磁盘,具体取决于您拥有多少行以及每行更新多少次。
  • 您实际上可以将计数存储在(单独的)计数器表中。所以,写到名单上,撞上柜台。如果两次写入,计数器仍然有正确的值,因为计数器被撞了两次。
  • 鉴于此,您只需要决定如何处理数据行的历史值。你需要它们吗?然后保留日志。还是你覆盖它们?这将意味着更少的磁盘,并且在日期上“最后写入获胜”。
  • 您能否将您的解决方案作为答案而不是问题的一部分?

标签: cassandra nosql


【解决方案1】:

在那里找到了解决方案:Cassandra 2.0,轻量级事务http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_ltwt_transaction_c.html

如果我执行查询:

update table1 set version_num = 5 where name = 'abc'  if version_num = 4;

我将收到带有[applied] 列的行。此行包含布尔值:true = 更新成功,false = 在其他情况下。

【讨论】:

    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 2013-04-02
    相关资源
    最近更新 更多