【问题标题】:Neo.ClientError.Statement.EntityNotFound when deleting and then creating nodes in parallel using transactional Neo4j REST APINeo.ClientError.Statement.EntityNotFound 删除然后使用事务性 Neo4j REST API 并行创建节点时
【发布时间】:2014-12-09 13:49:04
【问题描述】:

当我使用事务性 REST API 和并行自动提交模式在 Neo4j 数据库(v2.1.6,Ubuntu)中删除然后创建节点时,我会收到类似这样的错误

{"results":[],"errors":[{"code":"Neo.ClientError.Statement.EntityNotFound","message":"Node with id 35275"}]}

对于每个节点我运行查询:

curl -X POST -d @data http://localhost:7474/db/data/transaction/commit -H "Content-Type:application/json; charset=UTF-8" -H Accept:application/json  >out$i  

以下语句

{
    "statements": [
    {
        "statement": "MATCH (k:Keyword {kwId: \"1\"}) DELETE k",
        "parameters": {}
    },
    {
        "statement": "CREATE (k:Keyword {props}) RETURN k",
        "parameters": {
            "props": {
                "kwId": "1"
            }
        }
    }
    ]
}

每个查询的 kwId 值都不同。

当我按顺序执行查询时,一切都很好

当我并行运行查询时,我得到了一些查询的错误响应(20 个查询约 5 个错误响应)

{"results":[],"errors":[{"code":"Neo.ClientError.Statement.EntityNotFound","message":"Node with id 35275"}]}

这是 Neo4j 的问题还是我用错了?

重现问题的脚本:

#!/bin/bash
NEO4J_URL=http://localhost:7474
TOTAL_QUERIES=20

# Create temp JSON files tmp1.json, tmp2.json, ....
for (( i=1; i<$TOTAL_QUERIES; i++ ))
do
  JSON=tmp$i.json
  cat > $JSON << END_OF_JSON
{
    "statements": [
    {
            "statement": "MATCH (k:Keyword {kwId: \"$i\"}) DELETE k",
            "parameters": {}
    },
        {
            "statement": "CREATE (k:Keyword {props}) RETURN k",
            "parameters": {
                "props": {
                    "kwId": "$i"
                }
            }
        }
    ]
}
END_OF_JSON
done

for (( i=1; i<$TOTAL_QUERIES; i++ ))
do
  JSON=tmp$i.json
  if [ "$1" = "sync" ]; then
    curl --silent -X POST -d @$JSON $NEO4J_URL/db/data/transaction/commit -H "Content-Type:application/json; charset=UTF-8" -H Accept:application/json  >out$i  
  else
    curl --silent -X POST -d @$JSON $NEO4J_URL/db/data/transaction/commit -H "Content-Type:application/json; charset=UTF-8" -H Accept:application/json  >out$i &
  fi
done

wait
awk 'FNR==1{print ""}1' out* > result
grep "\"errors\":\[.*\]" result
rm out* tmp*.json result

更新:使用旧版 REST API 时,错误消息会更好

  "message" : "Node with id 35970",
  "exception" : "EntityNotFoundException",
  "fullname" : "org.neo4j.cypher.EntityNotFoundException",
  "stacktrace" : [ "org.neo4j.cypher.internal.spi.v2_1.TransactionBoundQueryContext$NodeOperations.getById(TransactionBoundQueryContext.scala:160)", "org.neo4j.cypher.internal.spi.v2_1.TransactionBoundQueryContext$$anonfun$getNodesByLabel$1.apply(TransactionBoundQueryContext.scala:135)", "org.neo4j.cypher.internal.spi.v2_1.TransactionBoundQueryContext$$anonfun$getNodesByLabel$1.apply(TransactionBoundQueryContext.scala:135)", "org.neo4j.cypher.internal.helpers.JavaConversionSupport$$anon$2.next(JavaConversionSupport.scala:33)", "scala.collection.Iterator$$anon$11.next(Iterator.scala:328)", "scala.collection.Iterator$$anon$13.next(Iterator.scala:372)", "scala.collection.Iterator$$anon$14.hasNext(Iterator.scala:389)", "scala.collection.Iterator$class.foreach(Iterator.scala:727)", "scala.collection.AbstractIterator.foreach(Iterator.scala:1157)", "scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)", "scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:176)", "scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:45)", "scala.collection.TraversableOnce$class.to(TraversableOnce.scala:273)", "scala.collection.AbstractIterator.to(Iterator.scala:1157)", "scala.collection.TraversableOnce$class.toList(TraversableOnce.scala:257)", "scala.collection.AbstractIterator.toList(Iterator.scala:1157)", "org.neo4j.cypher.internal.compiler.v2_1.pipes.EagerPipe.internalCreateResults(EagerPipe.scala:32)", "org.neo4j.cypher.internal.compiler.v2_1.pipes.PipeWithSource.createResults(Pipe.scala:105)", "org.neo4j.cypher.internal.compiler.v2_1.pipes.PipeWithSource.createResults(Pipe.scala:102)", "org.neo4j.cypher.internal.compiler.v2_1.pipes.PipeWithSource.createResults(Pipe.scala:102)", "org.neo4j.cypher.internal.compiler.v2_1.pipes.PipeWithSource.createResults(Pipe.scala:102)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:120)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:119)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionWorkflowBuilder.runWithQueryState(ExecutionPlanBuilder.scala:168)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:118)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:103)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:68)", "org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:67)", "org.neo4j.cypher.internal.ExecutionPlanWrapperForV2_1.execute(CypherCompiler.scala:159)", "org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:76)", "org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:71)", "org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:84)", "org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:114)", "java.lang.reflect.Method.invoke(Method.java:606)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "java.lang.Thread.run(Thread.java:745)" ],

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    不确定这是否有帮助,但我注意到了一件随机的事情:您使用的是 CREATE 参数,而不是 DELETE。我不知道这是否/为什么会导致竞争条件,但值得检查

    【讨论】:

    • 谢谢布赖恩。我已经检查了 DELETE 参数
    • 不幸的是,这无助于解决问题
    【解决方案2】:

    执行这两个查询似乎也有点奇怪。也许您剥离了一些机密内容,但我认为您可以这样做:

    MATCH (k:Keyword) WHERE k.kwId IN ({kw_ids}) DELETE k WITH k.kwId AS kwId CREATE (:Keyword:  {kwId: kwId})
    

    【讨论】:

    • 你是对的。我错过了所有与问题无关的东西以简化事情。在实际用例中,查询删除具有现有关系的节点并添加具有新属性和关系的新节点。由于遗留代码(我们正在从其他数据库迁移到 Neo4j),我无法在单个查询中组合所有语句。节点是分开处理的,节点数量很大,大约 100 万左右。无论如何,感谢布赖恩的时间和建议。我将尝试探索他们的代码以了解发生了什么。
    【解决方案3】:

    在属性 kwId 上创建新索引似乎可以解决我的问题

    CREATE INDEX ON :Keyword(kwId)
    

    【讨论】:

      猜你喜欢
      • 2013-04-28
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多