我在我的应用程序中发现了一个并发问题,其中有两个线程试图在Neo4J v2.2.5中的同一节点或关系上同时执行写操作。
我设法用简单的方法再现了这个问题:
conf/neo4j.properties中添加allow_store_upgrade=true以启用自动数据库升级。$ ./test.sh这是我得到的结果:
{
"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上是否有锁定机制可以用来防止这个问题?
发布于 2015-10-08 09:13:05
你在观察一种典型的比赛状态。为了防止这种情况,您需要在Claude节点上获取一个锁。Cypher没有显式抓取锁的语法,所以我们只是将一个假属性设置为第一个动作,并在最后删除该属性--这有抓取锁的副作用。因此,请更改您的两项声明:
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 mhttps://stackoverflow.com/questions/33001468
复制相似问题