Neo4j/Cypher 并发合并
Neo4j/Cypher concurrent MERGE
我编写了一个执行并发 MERGE
请求的简单测试,发现在空数据库上创建了多个节点,尽管我希望有唯一节点。
[Test]
public void ConcurrentNodeMerge()
{
// act
Parallel.ForEach(Enumerable.Range(1, 10), index =>
{
client.Cypher
.Merge("(n:Node)")
.Set("n.Index = COALESCE(n.Index, '') + ' ' + {index}")
.WithParam("index", index.ToString())
.ExecuteWithoutResults();
});
// assert
var result = client.Cypher
.Match("(n:Node)")
.Return<string>("n.Index")
.Results;
Assert.That(result.Count(), Is.EqualTo(1));
}
我总是得到两个节点,索引字段如下所示
Index 8 3 7 5 2 10 6 1
Index 4 3 7 9 5 2 10 6 1
我希望有一个节点执行最新的索引。
注意 我用的是.NET Neo4jClient
我假设您对 :Node(index) 属性.
没有约束
CREATE CONSTRAINT ON (n:Node) ASSERT n.Index IS UNIQUE;
MERGE
不是保证唯一性的意思,它是保证ONLY具有唯一性约束。
解释为什么你得到重复项:并发 MERGE blah
操作受 race condition 约束,其中每个操作实例检测到 blah
尚不存在,导致每个继续创建 blah
.
避免这种情况的方法是使用 uniqueness constraints,如 @ChristopheWillemsen 所示。
我编写了一个执行并发 MERGE
请求的简单测试,发现在空数据库上创建了多个节点,尽管我希望有唯一节点。
[Test]
public void ConcurrentNodeMerge()
{
// act
Parallel.ForEach(Enumerable.Range(1, 10), index =>
{
client.Cypher
.Merge("(n:Node)")
.Set("n.Index = COALESCE(n.Index, '') + ' ' + {index}")
.WithParam("index", index.ToString())
.ExecuteWithoutResults();
});
// assert
var result = client.Cypher
.Match("(n:Node)")
.Return<string>("n.Index")
.Results;
Assert.That(result.Count(), Is.EqualTo(1));
}
我总是得到两个节点,索引字段如下所示
Index 8 3 7 5 2 10 6 1
Index 4 3 7 9 5 2 10 6 1
我希望有一个节点执行最新的索引。
注意 我用的是.NET Neo4jClient
我假设您对 :Node(index) 属性.
没有约束CREATE CONSTRAINT ON (n:Node) ASSERT n.Index IS UNIQUE;
MERGE
不是保证唯一性的意思,它是保证ONLY具有唯一性约束。
解释为什么你得到重复项:并发 MERGE blah
操作受 race condition 约束,其中每个操作实例检测到 blah
尚不存在,导致每个继续创建 blah
.
避免这种情况的方法是使用 uniqueness constraints,如 @ChristopheWillemsen 所示。