Neo4j的新闻是否有缺陷?

时间:2016-01-06 10:53:35

标签: neo4j cypher

我正在使用此示例http://neo4j.com/docs/stable/cypher-cookbook-newsfeed.html来维护用户的新闻源。所以我使用以下内容发布状态更新:

MATCH (me)
WHERE me.name='Bob'
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE (latest_update)-[:NEXT]->(x))
RETURN latest_update.text AS new_status

我遇到了严重的缺陷,并且不知道如何修复它。在非常罕见的情况下,两个状态更新在完全相同的时间(例如,相隔10毫秒)发布,而不是替换当前状态,Neo4j创建两个状态更新。这导致了一个更大的问题,即下次更新发布两次!

1 个答案:

答案 0 :(得分:3)

这看起来像竞争条件。要解决这个问题,您基本上需要确保在给定时间只有一个事务正在修改此特定用户的状态。

Neo4j的Java API确实能够设置锁定来实现这一目标。 Cypher没有明确的功能,但你可以这样做,例如删除不存在的属性以强制锁定给定节点。在锁定到位的情况下,并发事务需要等待,锁定的持有者完成了他的事务。

所以在声明的早期抓住锁:

MATCH (me)
WHERE me.name='Bob'
REMOVE me._not_existing // side effect: grab a lock early
WITH me
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE (latest_update)-[:NEXT]->(x))
RETURN latest_update.text AS new_status