首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Neo4J上的锁定机制

Neo4J上的锁定机制
EN

Stack Overflow用户
提问于 2015-10-07 20:04:21
回答 1查看 1.9K关注 0票数 2

我在我的应用程序中发现了一个并发问题,其中有两个线程试图在Neo4J v2.2.5中的同一节点或关系上同时执行写操作。

我设法用简单的方法再现了这个问题:

  1. 下载和导入示例neo4j电影数据库:2.1.6.zip,因为数据库是旧的,所以您必须在conf/neo4j.properties中添加allow_store_upgrade=true以启用自动数据库升级。
  2. 启动neo4j并在neo4jshell上运行此查询: 匹配(a:演员{name:"Claude Jade"}),(m:电影)合并(a)-:ACTS_IN->(m); 这将创建从“克劳德·杰德”演员到所有电影节点的ACTS_IN关系。这样做的原因是为了使删除"Claude“的Actor节点过程(见下文第4号)更长,因此并发问题发生的可能性更大。
  3. 下载curl命令行程序,如果你还没有。我们将使用curl将查询发送到neo4j。
  4. 创建一个bash脚本文件(文件名由您决定),内容如下: #!bin/bash curl -XPOST http://localhost:7474/db/data/transaction/commit -H "Content-Type: application/json“-d‘{”语句“:[{”语句“:”匹配“(n:参与者{name:\"Claude Jade\"})可选匹配(n)-r-()删除n,r"} }‘& curl -XPOST http://localhost:7474/db/data/transaction/commit -H“内容-Type: application/json”-d’{“语句”:[{“语句”:“匹配”(n:参与者{name:\"Claude Jade\}})创建(N)->(m:电影{标题:\"Hello \}}“)返回m"} ]}和等待 这将运行两个卷曲过程并行,其中第一个进程将试图删除“克劳德玉”演员和它的所有关系,第二个过程将试图创建新的ACTS_IN关系“克劳德玉”演员。
  5. 在bash上运行脚本文件,例如$ ./test.sh

这是我得到的结果:

代码语言:javascript
复制
{
    "results" : [{
            "columns" : ["m"],
            "data" : [{
                    "row" : [{
                            "title" : "Hello World"
                        }
                    ]
                }
            ]
        }
    ],
    "errors" : []
} {
    "results" : [{
            "columns" : [],
            "data" : []
        }
    ],
    "errors" : [{
            "code" : "Neo.DatabaseError.Transaction.CouldNotCommit",
            "message" : "org.neo4j.kernel.api.exceptions.TransactionFailureException: Node record Node[3150,used=false,group=55,prop=-1,labels=Inline(0x0:[]),light] still has relationships",
            "stackTrace" : "java.lang.RuntimeException: org.neo4j.kernel.api.exceptions.TransactionFailureException: Node record Node[3150,used=false,group=55,prop=-1,labels=Inline(0x0:[]),light] still has relationships\r\n\tat org.neo4j.server.rest.transactional.TransitionalTxManagementKernelTransaction.commit(TransitionalTxManagementKernelTransaction.java:87)\r\n\tat org.neo4j.server.rest.transactional.TransactionHandle.closeContextAndCollectErrors(TransactionHandle.java:278)\r\n\tat 
            ...

注意:如果您没有看到任何事务错误,那么您必须重新导入电影数据库并重新运行上述步骤。

因此,据我所见,删除失败是因为它试图删除Actor节点及其所有ACTS_IN关系,它首先执行了匹配查询(MATCH (n:Actor {name: \"Claude Jade\"}) OPTIONAL MATCH (n)-[r]-()),但在执行DELETE n, r之前,第二个进程设法将新的ACTS_IN关系插入到Actor节点,这就是为什么删除失败的原因,因为当它尝试执行删除时,Actor已经添加了一个新的关系。

我想知道Neo4J上是否有锁定机制可以用来防止这个问题?

EN

回答 1

Stack Overflow用户

发布于 2015-10-08 09:13:05

你在观察一种典型的比赛状态。为了防止这种情况,您需要在Claude节点上获取一个锁。Cypher没有显式抓取锁的语法,所以我们只是将一个假属性设置为第一个动作,并在最后删除该属性--这有抓取锁的副作用。因此,请更改您的两项声明:

代码语言:javascript
复制
MATCH (n:Actor {name: "Claude Jade"}) 
SET n._fake = 1   // grabs the lock as first action
WITH n
OPTIONAL MATCH (n)-[r]-() 
DELETE n, r

MATCH (n:Actor {name: "Claude Jade"}) 
SET n._fake = 1 // grab the lock early
CREATE (n)-[:ACTS_IN]->(m:Movie {title: "Hello World"}) 
REMOVE n._fake   // get rid of fake property
RETURN m
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33001468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档