我MERGE
在10个并行线程中从客户端应用程序对我的Neo4j服务器运行以下查询,newFoo
并且id
所有10个运行中的参数相同:
MERGE (foo:Foo { id: {id} }) ON MATCH SET foo = {newFoo}
运行此之后,我运行以下查询以期望1
但我得到10
:
match (f:Foo) return count(f)
我认为这MERGE
是在原子事务中运行但显然不是.我在这里做错了吗?
下面是我用来重现该问题的代码:
public static async Task RunInParallel() { var client = new GraphClient(new Uri("http://localhost:7474/db/data"), "neo4j", "1234567890") { JsonContractResolver = new CamelCasePropertyNamesContractResolver() }; client.Connect(); var foo = new Foo { Id = "1", Name = "Foo", Slug = "foo-bar-foo" }; Listtasks = new List (); for (int i = 0; i < 10; i++) { var task = client.Cypher .Merge("(foo:Foo { id: {id} })") .OnMatch() .Set("foo = {newFoo}") .WithParams(new { Id = foo.Id, NewFoo = foo }) .ExecuteWithoutResultsAsync(); tasks.Add(task); } await Task.WhenAll(tasks.ToArray()); }
William Lyon.. 5
MERGE
(单独)不保证唯一性.使用MERGE
(在唯一属性上)时,应始终为指定的属性创建唯一性约束:
CREATE CONSTRAINT ON (f:Foo) ASSERT f.id IS UNIQUE
这将确保您不会创建任何重复项.
编辑
MERGE
没有唯一性约束不是线程安全的.添加唯一性约束可确保在写入之前保持索引锁定,从而使操作线程安全.
MERGE
(单独)不保证唯一性.使用MERGE
(在唯一属性上)时,应始终为指定的属性创建唯一性约束:
CREATE CONSTRAINT ON (f:Foo) ASSERT f.id IS UNIQUE
这将确保您不会创建任何重复项.
编辑
MERGE
没有唯一性约束不是线程安全的.添加唯一性约束可确保在写入之前保持索引锁定,从而使操作线程安全.