如何从Cassandra中删除一行并获取删除前的值?
我可以依次执行一个SELECT
和DELETE
查询,但是如何确定在执行这两个查询之间没有同时更改数据?
我试图批量执行SELECT
和DELETE
查询,但这似乎是不允许的。
cqlsh:foo> BEGIN BATCH
... SELECT * FROM data_by_user WHERE user = 'foo';
... DELETE FROM data_by_user WHERE user = 'foo';
... APPLY BATCH;
SyntaxException: line 2:4 mismatched input 'SELECT' expecting K_APPLY (BEGIN BATCH [SELECT]...)
在我的用例中,我有一个主表来存储项目数据。我已经建立了几个表,可以根据这些信息查找项目。 如果要从主表中删除项目,则还必须将其从其他表中删除。
CREATE TABLE items (id text PRIMARY KEY, owner text, liking_users set<text>, ...);
CREATE TABLE owned_items_by_user (user text, item_id text, PRIMARY KEY ((user), item_id));
CREATE TABLE liked_items_by_user (user text, item_id tect, PRIMARY KEY ((user), item_id));
...
如果我删除一个项目,同时又有人删除了一个表,恐怕表格中可能包含错误的数据。点击相同项目的“赞”按钮。
deleteItem
方法执行SELECT
查询以从主表中获取项目的当前行likeItem
方法运行一个UPDATE
查询,并将该项目插入到owned_items_by_user
,liked_items_by_user
,...表中。在执行SELECT
语句后执行UPDATE
查询,然后再执行DELETE
查询。deleteItem
方法根据刚通过owned_items_by_user
语句检索的数据从liked_items_by_user
,SELECT
,...表中删除项目。该数据尚未包含刚刚添加的内容。因此,该项目已删除,但刚刚添加的类似项仍保留在liked_items_by_user
表中。答案 0 :(得分:2)
您可以事先进行选择,然后对删除执行轻量级事务,以确保数据看起来仍然与选择时完全一样。如果是这样,则在删除之前,您会知道最新状态。如果没有,请继续重试整个过程,直到遇到问题为止。
答案 1 :(得分:0)
不幸的是,您无法在批处理语句中执行$('[name="event"]').on('change', function() {
if ($(this).attr('id') == 'walkEvent') {
$('#place').text('Meeting point: ');
} else {
$('#place').text('Location: ');
}
});
查询。如果您阅读文档here,则只能使用插入,更新和删除语句。
您要查找的是执行的原子性,但是批处理语句不会成为前进的方向。如果数据已更改,则最坏的情况是僵尸或可能重新出现的数据。
Cassandra使用成绩周期机制来处理此问题,您可以找到详细信息here。如果出于某种原因这对您的业务逻辑至关重要,那么在这种情况下您可以做的“最好”的事情是提高一致性级别,或者在应用程序级别重构读取模式以不依赖完美的原子性,无论哪种交易正确送给你因此,要么放弃某些性能,要么调低要求。
实际上,<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="event" id="walkEvent" value="walkEvent"/><label>Walk Event</label>
<input type="radio" name="event" id="otherEvent" value="otherEvent"/><label>Other Event</label>
<p><label id="place">Meeting Point / Location: </label><input type="text" name="meeting_or_location"/></p>
应该足以满足大多数情况下的大多数情况。另外,您可以执行SELECT
,并付出性能损失,但这意味着给定QUORUM
分区键的所有副本都必须确认ALL
和foo
。注意,这仍然意味着提交日志中的commitlog
必须在删除memtable
之前发生,但是您可以将一致性调整到所需的级别。
从SQL的角度来讲,您没有原子性,但是根据吞吐量的不同,您不太可能需要它(触摸木头)。
TLDR:
flush
应该可以解决问题。您现在看到的错误基本上是CQL 3的ANTLR3语法解析器,其设计目的并不是仅仅因为不支持它们而接受批内的SELECT查询,您可以看到 here 。