当前位置:  开发笔记 > 前端 > 正文

Neo4j Merge和Atomic Transaction

如何解决《Neo4jMerge和AtomicTransaction》经验,为你挑选了1个好方法。

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"
    };

    List tasks = 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没有唯一性约束不是线程安全的.添加唯一性约束可确保在写入之前保持索引锁定,从而使操作线程安全.



1> William Lyon..:

MERGE(单独)不保证唯一性.使用MERGE(在唯一属性上)时,应始终为指定的属性创建唯一性约束:

CREATE CONSTRAINT ON (f:Foo) ASSERT f.id IS UNIQUE

这将确保您不会创建任何重复项.

编辑

MERGE没有唯一性约束不是线程安全的.添加唯一性约束可确保在写入之前保持索引锁定,从而使操作线程安全.


@DavidFox感谢您的反馈.我会把它传递给你.在没有唯一性约束的情况下使用MERGE不是线程安全的.添加唯一性约束可通过使用索引锁来确保MERGE的线程安全性.
谢谢@WilliamLyon.对文档中的一些反思肯定会有用.我以前遇到过类似的问题,对我而言,似乎可以用更好的方式记录锁定Neo4j的概念.另外,我对锁定系统的细节并不太熟悉,但对我而言,简单的MERGE查询会陷入僵局似乎很奇怪,因为MERGE的重点是创建或返回/更新已经存在的实体.
推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有