1

现在您是否在 Neo4j 2.0 中创建事务?我尝试了几十种方法,但都没有奏效。

基本上问题是第二次和后续交易永远不会成功。也许我没有正确开始交易。我不知道。我尝试了我在您的单元测试和ExecutionEngine.

这是我创建交易的方式:

  private def withTransaction[T](f: => T): T = {
    // FIXME: Sometimes it returns PlaceboTransaction which causes TONS of issues
    val tx = db.beginTx
    try {
      val result = f
      tx.success()
      result
    } catch {
      case e: Throwable =>

        // If I don't check this I'll get NullPointerException in TopLevelTransaction.markAsRollbackOnly()
        if (!tx.isInstanceOf[PlaceboTransaction])
          tx.failure()

        throw e
    } finally {

      // If I don't check this I'll get NullPointerException in TopLevelTransaction.markAsRollbackOnly()
      if (!tx.isInstanceOf[PlaceboTransaction])
        tx.close()

    }
  }

它永远不会起作用。尝试获取节点的任何数据/属性会导致以下异常

Exception in thread "main" org.neo4j.graphdb.NotInTransactionException
    at org.neo4j.kernel.ThreadToStatementContextBridge.transaction(ThreadToStatementContextBridge.java:58)
    at org.neo4j.kernel.ThreadToStatementContextBridge.statement(ThreadToStatementContextBridge.java:49)
    at org.neo4j.kernel.impl.core.NodeProxy.hasLabel(NodeProxy.java:551)
    at GraphDBManager$$anonfun$findUsers$1$$anonfun$apply$1.apply(GraphDBManager.scala:72)
    at GraphDBManager$$anonfun$findUsers$1$$anonfun$apply$1.apply(GraphDBManager.scala:72)
    at scala.collection.TraversableLike$WithFilter$$anonfun$map$2.apply(TraversableLike.scala:722)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$WithFilter.map(TraversableLike.scala:721)
    at GraphDBManager$$anonfun$findUsers$1.apply(GraphDBManager.scala:72)
    at GraphDBManager$$anonfun$findUsers$1.apply(GraphDBManager.scala:72)
    at GraphDBManager$.withTransaction(GraphDBManager.scala:38)
    at GraphDBManager$.findUsers(GraphDBManager.scala:71)
    at Test$.main(Test.scala:12)
    at Test.main(Test.scala)

我在这里创建了示例项目。

任何帮助是极大的赞赏。谢谢。

4

2 回答 2

2

好吧..经过数小时的调试,我想通了。我希望它会在最终版本中得到修复。

这是问题函数的样子

def findUsers: List[ObjectId] = {
  val query = engine.execute(s"MATCH (n:$label) RETURN n")
  val it = query.columnAs[Node]("n")

  withTransaction {
    val lst = it.toList
    val ret = for (node <- lst; if node.hasLabel(label)) yield new ObjectId(node.getProperty("id").asInstanceOf[String])
    ret
  }
}

结果是让ExecutionEngine.execute交易打开,导致beginTx()回报而不是真正的交易对象。另一方面,我无法摆脱我的事务包装器,因为令人惊讶地以不同的方式获取事务对象withTransactionPlaceboTransactionNodeProxy

Exception in thread "main" org.neo4j.graphdb.NotInTransactionException
    at org.neo4j.kernel.ThreadToStatementContextBridge.transaction(ThreadToStatementContextBridge.java:58)
    at org.neo4j.kernel.ThreadToStatementContextBridge.statement(ThreadToStatementContextBridge.java:49)
    at org.neo4j.kernel.impl.core.NodeProxy.hasLabel(NodeProxy.java:551)

它来自哪里

private KernelTransaction transaction()
{
    checkIfShutdown();
    KernelTransaction transaction = txManager.getKernelTransaction();
    if ( transaction == null )
    {
        throw new NotInTransactionException();
    }
    return transaction;
}

getKernelTransaction我不知道来自 TLS 映射的事务和对象之间有什么区别。

因此我的功能的固定版本将是

def findUsers: List[ObjectId] = {
  val query = engine.execute(s"MATCH (n:$label) RETURN n")
  val it = query.columnAs[Node]("n")
  val lst = it.toList
  query.close()

  withTransaction {
    val ret = for (node <- lst; if node.hasLabel(label)) yield new ObjectId(node.getProperty("id").asInstanceOf[String])
    ret
  }
}

在我看来,这不仅从设计的角度来看很难看,而且当我在第二次交易中遍历节点时也会给出不一致的数据。

于 2013-10-22T18:17:25.030 回答
2

这是一个客户端代码错误,这里有问题的项目的拉取请求:https ://github.com/cppexpert/neo4j_2_bad_transactions/pull/1

于 2013-10-23T09:42:58.370 回答