问题描述
我正在10个并行线程中从客户端应用程序对我的Neo4j服务器运行以下MERGE
查询,newFoo
和id
参数在所有10次运行中都相同:
I am running the below MERGE
query against my Neo4j server from a client application in 10 parallel threads, the newFoo
and id
parameters are the same on all 10 runs:
MERGE (foo:Foo { id: {id} })
ON MATCH
SET foo = {newFoo}
运行此命令后,我运行以下查询以期望1
,但我却得到了10
:
After running this, I run the below query to expect 1
but I instead get 10
:
match (f:Foo)
return count(f)
我认为MERGE
在原子事务中运行,但显然不是.我在这里做错什么了吗?
I thought that MERGE
runs in an atomic transaction but apparently not. Am I doing something wrong here?
下面是我用来重现该问题的代码:
Below is the code that I used to reproduce the issue:
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"
};
List<Task> tasks = new List<Task>();
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());
}
推荐答案
MERGE
(本身)不能保证唯一性.在唯一属性上使用MERGE
时,应始终创建唯一性约束指定的属性:
MERGE
(by itself) does not guarantee uniqueness. When using MERGE
(on a unique property) you should always create a uniqueness constraint for the specified property:
CREATE CONSTRAINT ON (f:Foo) ASSERT f.id IS UNIQUE
这将确保您不会创建任何重复项.
This will ensure you aren't creating any duplicates.
修改
MERGE
不是线程安全的.添加唯一性约束可确保在写入之前保持索引锁,从而使操作线程安全.
MERGE
without a uniqueness constraint is not thread safe. Adding a uniqueness constraint ensures an index lock is held before writing, making the operation thread safe.
这篇关于Neo4j合并和原子事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!