我有一个相当复杂的Web应用程序,可以在Cassandra数据库中创建HTML页面。
在创建页面时,它会在该页面中保存一个状态,反映出正在处理的事实。
INSERT INTO content (key, column1, value)
VALUES ('http://domain/path', 'content:status', 0x0201);
(列名来自节俭日......)
当状态为0x0201时,没有其他进程可以对页面执行任何操作。它被视为已锁定。
创建页面后,只需一毫秒左右,我将状态切换为"正常"。这是content::status
字段的另一个插入。
INSERT INTO content (key, column1, value)
VALUES ('http://domain/path', 'content:status', 0x0102);
此处状态从0x0201
更改为0x0102
。仅在我在网站初始化时创建的大约700页中,该状态在22到30个(3%到4%)内没有变化。
这是否会发生,因为第一个INSERT INTO
和第二个{{1}}之间的时间太短而Cassandra集群混淆了? (即看到两者一起到达并且它选择其中一个,在这几个失败的情况下恰好是错误的?)
答案 0 :(得分:0)
当使用C ++驱动程序(以及其他我确定的)时,两个INSERT命令可能最终被发送到两个不同的管道。这是因为驱动程序处理工作线程,并且命令最终可以在任一工作线程管道中完成。
这意味着即使你发送CREATE和更高版本的NORMAL,线程管道也可能最先发送NORMAL然后再发送到Cassandra(即交换数据首次发送到C ++驱动程序的顺序。)然后你最终状态为CREATE ...
这无法直接解决。相反,您可能希望在该页面上工作时使用锁定,一旦完成工作,还要将状态更新为NORMAL,以防其他情况,然后解锁。如果你有一个超时锁定,那么你永远不应该创建一个完整的死锁(即一个进程处理页面A然后是B而没有在处理B之前释放第A页上的锁定,而另一个进程首先处理页面B然后A ... )