Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j/Cypher在高度并发的环境中创建独特的关系_Neo4j_Cypher_Graph Databases_Nosql - Fatal编程技术网

Neo4j/Cypher在高度并发的环境中创建独特的关系

Neo4j/Cypher在高度并发的环境中创建独特的关系,neo4j,cypher,graph-databases,nosql,Neo4j,Cypher,Graph Databases,Nosql,对于给定的关系类型,我需要有某种唯一的约束 (a)-[:RELATION]->(b) 为了实现这一点,我正在使用createunique(a)-[:RELATION]->(b) 在并发环境中,如果多个线程可以在相同的节点之间创建(a)-[:RELATION]->(b),我将得到UniquePathNotUniqueException,以及由于neo4j事务隔离的性质而创建的多个关系 我发现目前创建唯一关系的唯一方法是写锁两个节点 有没有其他方法可以保证建立独一无二的关系 更新 这就是我最

对于给定的关系类型,我需要有某种唯一的约束

(a)-[:RELATION]->(b)
为了实现这一点,我正在使用
createunique(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_
MATCH (a), (b) 
SET a._lock_ = true, b._lock_ = true 
MERGE (a)-[:RELATION]->(b) 
REMOVE a._lock_, b._lock_

使用额外的重试循环和指数回退过程,可能会出现死锁。

您需要对关系使用
合并
,但事先需要获取锁以防止并发问题。作为移除不存在的属性的副作用,这是最容易做到的:

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)
MATCH(a:Label{key:value}),(b:Label{key:value2})
对于a、b,当id(a)(b)

这就是我在最后使用的方法

MATCH (a), (b) 
SET a._lock_ = true, b._lock_ = true 
MERGE (a)-[:RELATION]->(b) 
REMOVE a._lock_, b._lock_
MATCH (a), (b) 
SET a._lock_ = true, b._lock_ = true 
MERGE (a)-[:RELATION]->(b) 
REMOVE a._lock_, b._lock_

使用额外的重试循环和指数回退来处理可能的死锁。

您是否尝试了
MERGE(a)-[:RELATION]->(b)
?我认为应该隐式地处理写锁。merge不能保证唯一性do
a
b
已经存在于图形中,并且您正在匹配它们?如果是这样的话,我很确定在这种情况下,
MERGE
将在它们上获取一个写锁。这两个节点都已经存在<代码>合并不接受写锁,关系唯一性也不保证。试着做些测试,我不完全正确。当我们创建关系时,
MERGE
将在两个节点上获取锁,但因为我们在匹配时不锁定节点,所以在并发执行查询时可能会创建重复关系。在我的情况下,remove-non-existence属性不起作用。但设置和删除节点上的属性会起作用<代码>匹配(a),(b)设置a