我需要为给定的关系类型提供某种独特的约束。
(a)-[:RELATION]->(b)
为了达到这个目的,我正在使用CREATE UNIQUE (a)-[:RELATION]->(b)
在并发环境中,如果多个线程可以在相同节点之间创建(a)-[:RELATION]->(b)
,那么我将获得UniquePathNotUniqueException
,并且由于neo4j事务隔离的性质而创建了多个关系。
我发现目前创建唯一关系的唯一方法是对两个节点进行写锁定。
还有其他方法可以创造有保障的独特关系吗?
更新
这就是我最后使用的方法
MATCH (a), (b)
SET a._lock_ = true, b._lock_ = true
MERGE (a)-[:RELATION]->(b)
REMOVE a._lock_, b._lock_
使用额外的重试循环,指数退避过程可能出现死锁。
答案 0 :(得分:3)
您需要在关系上使用MERGE
,但事先需要获取锁以防止并发问题。这是移除非现有属性的副作用最容易实现的:
MATCH (a:Label{key:value}), (b:Label{key:value2})
REMOVE a._non_existing_property, b._non_existing_property
MERGE (a)-[:RELATION]->(b)
我上面的陈述有死锁的危险(Neo4j会检测并妥善处理)。为了防止必须按照一致的顺序进行锁定,例如通过较小的节点ID:
MATCH (a:Label{key:value}), (b:Label{key:value2})
WITH a, b, case when id(a) < id(b) then a else b end as locknode
REMOVE locknode._non_existing_property
MERGE (a)-[:RELATION]->(b)
答案 1 :(得分:0)
这就是我最后使用的方法
MATCH (a), (b)
SET a._lock_ = true, b._lock_ = true
MERGE (a)-[:RELATION]->(b)
REMOVE a._lock_, b._lock_
使用指数退避的附加重试循环来处理可能的死锁。