Cassandra 上的事务“检查并插入”

Transaction `Check and Insert` on Cassandra

CREATE TABLE table (
  id1 uuid,
  bucket timestamp,
  createdat timestamp,
  id2 uuid,
  data blob,
  
  primary key((id1, bucket), createdat, id2)
)
with
  clustering ORDER BY (createdat ASC, id2 ASC) AND ...

我有这个 Cassandra table。在多线程环境中,两个线程可以同时向此 table 插入行。 我要求 table 不应有两行具有相同的 (id1bucket) 和 data 字段且值为 null。 这意味着只有 table 的最后一行(每个 id1bucket)可以有 data 作为 null。 为了在每次插入之前实现这一点,我查询 table 的最后一行,并且仅当 data 字段不为空时才插入新行。 由于竞争条件,这不起作用。两个线程都检查,获取没有 data 的最后一行为 null 并插入具有 null 的行,因此违反了要求。

我认为可以在数据库级别修复此问题。我需要一些首先检查最后一行然后才插入新行的事务。在这些操作之间不应插入任何内容。

您能否提示如何在 Cassandra 上实现这一点?

您或许可以让此行为与 Lightweight Transaction 一起使用。

在您的情况下,它可能类似于:

INSERT INTO table (id1,bucket,createdat,id2,data)
VALUES (uuid(),'2021-09-27 13:20',totimestamp(now()),uuid(),'some data')
IF NOT EXISTS;

基本上,这只会在组合键不存在的情况下执行写入。这个确切的解决方案可能行不通,但它应该为您指明正确的方向。

在 Cassandra 中无法实现这一点。正如您已经说过的,您将始终 运行 进入竞争条件。

除了轻量级事务外,Cassandra 没有锁定机制,因为它违背了高速 CRUD 操作的目标。干杯!