2016-11-17 37 views
1

我正在运行Neo4j 3.0.6,并且正在将大量数据导入来自多个来源的新实例。我使用下面的约束强制唯一性:Neo4j 3.0.6唯一性约束被MERGE侵犯

CREATE CONSTRAINT ON (n:Person) ASSERT n.id IS UNIQUE 

我会再进口数据和来自多个来源的关系和多线程:

MERGE (mother:Person{id: 22}) 
MERGE (father:Person{id: 55}) 
MERGE (self:Person{id: 128}) 
SET self += {name: "Alan"} 
MERGE (self)-[:MOTHER]->(mother) 
MERGE (self)-[:FATHER]->(father) 

同时,在另一个线程,但还是一样Neo4j的服务器上,螺栓终点,我将导入数据的其余部分:

MERGE (husband:Person{id: 55}) 
MERGE (self:Person{id: 22}) 
SET self += {name: "Phyllis"} 
MERGE (self)-[:HUSBAND]->(husband) 
MERGE (wife:Person{id: 22}) 
MERGE (self:Person{id: 55}) 
SET self += {name: "Angel"} 
MERGE (self)-[:WIFE]->(wife) 
MERGE (brother:Person{id: 128}) 
MERGE (self:Person{id: 92}) 
SET self += {name: "Brian"} 
MERGE (self)-[:BROTHER]->(brother) 
MERGE (self)<-[:BROTHER]-(brother) 

最后,如果我再次运行约束命令,我得到这个:

Unable to create CONSTRAINT ON (Person:Person) ASSERT Person.id IS UNIQUE: 
Multiple nodes with label `Person` have property `id` = 55: 
    node(708823) 
    node(708827) 

不保证其订购的记录将被处理,结束意外事件发生的多条记录为同一(:Person{id}) GET创建,但只有一个人填充了name数据。

看来Neo4j有一个竞赛条件,如果两个MERGE同时发生同一个id,它们都将被创建。有没有办法避免这种竞争条件?有没有办法建立必要的锁?

可能重复:Neo4J 2.1.3 Uniqueness Constraint Being Violated, Is This A Bug?但是,这是CREATEthis google groups answer表明CREATE中对于限制行为与MERGE不同。

+1

删除我的答案,因为它不再适用于您的更新说明。如果我能想出一些更好的解决方案,我会提交另一个答案。 – InverseFalcon

+0

谢谢InverseFalcon。对不起,我错误的语法促使你写出这样一个完整有用的答案,只有我才能看到。我给了你一些额外的代表,希望能弥补它:) – wizulus

+0

只是出于好奇,如果你把你的SET改成'ON CREATE SET ...'和'ON MERGE SET ...',你会怎么样?与重复节点? – InverseFalcon

回答

0

我知道您可以在某个节点上获得隐式锁定,然后将其用于同步,但我认为这会有效地序列化处理,因此处理不会真正被同时处理。

总的来说,我认为一个更好的方法是放弃在多个线程中处理相同类型的数据,只需在一个线程上向MERGE:人员进行单一导入并设置其属性。

在导入之后,您可以处理您的关系创建,并且理解您将匹配而不是MERGEing:人员。