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 所示。