2016-05-23 11 views
0

私は、同時のMERGEリクエストを実行するシンプルなテストを書いて、空のデータベースには一意のノードがあると思われるが複数のノードが作成されていることがわかりました。Neo4j/Cypher concurrent 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 

以下のように私は常にインデックスフィールドを持つ2つのノードで終わります。

私は私はあなたが上の制約はありませんと仮定.NET Neo4jClient

答えて

2

を使用:ノード(インデックス)プロパティを。

CREATE CONSTRAINT ON (n:Node) ASSERT n.Index IS UNIQUE; 

MERGE一意性を保証することを意味していない、それがONLYユニーク制約を持つことが保証されます。

1

あなたは重複を得ている理由を説明する:同時MERGE blah操作は、操作の各インスタンスは、それぞれが先に行くとblahを作成させ、blahがまだ存在していないことを検出し、前記race conditionの対象となっています。

@ChristopheWillemsenが示すように、uniqueness constraintsを使用してこの状況を回避する方法があります。

+0

将来の読者のために、いくつかのNeo4jバージョン(3.0.xバージョンの場合は3.0.9未満、3.1.xバージョンの場合は3.1.2バージョン)のバグの結果、競合状態が修正されました。 MERGEが重複したノードを作成できないように、常に保証をロックするためのものです。 – InverseFalcon