1

Neo4j 2.0 でトランザクションを作成しますか? 何十もの方法を試しましたが、どれもうまくいきませんでした。

基本的に問題は、2 回目以降のトランザクションが成功しないことです。おそらく、私は適切に取引を開始していません。知らない。あなたの単体テストと で見られるすべての可能な組み合わせを試しました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

これはクライアント コードのバグでした。問題のプロジェクトへのプル リクエストはこちら: https://github.com/cppexpert/neo4j_2_bad_transactions/pull/1

于 2013-10-23T09:42:58.370 に答える
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;
}

TLS マップからのトランザクションと TLS マップからのオブジェクトの違いは何ですか?getKernelTransactionわかりません。

したがって、私の関数の修正版は

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

私の意見では、これは設計の見通しから醜いだけでなく、2番目のトランザクションでノードを反復処理するときに一貫性のないデータを提供します。

于 2013-10-22T18:17:25.030 に答える