当我试图调用我的插件时,neo4j说我需要在一个事务中包装我的调用

时间:2016-06-15 16:32:05

标签: neo4j

我正在尝试为neo4j 3.0.0编写插件。为了测试水,我写了这个非常简单的方法来揭示外向度。

public class Utils extends ServerPlugin {
    @PluginTarget(value = Node.class)
    public int outgoingDegree(@Source Node node) {
        return node.getDegree(Direction.OUTGOING);
    }
}

注册插件的工作完美无缺:

curl -v http://localhost:7474/db/data/ext/

{
  "Utils" : "http://localhost:7474/db/data/ext/Utils"
}

我的小方法就在那里:

curl -v http://localhost:7474/db/data/ext/Utils

{
  "node" : {
    "outgoingDegree" : {
      "extends" : "node",
      "name" : "outgoingDegree",
      "description" : "",
      "parameters" : [ ]
    }
  }
}

惊人。现在当我尝试调用这种方法时,一切都走下坡路了:

url -XPOST -v http://localhost:7474/db/data/ext/Utils/node/20/outgoingDegree -H "Accept: application/json" -H "Content-type: application/json" -d "{ }"

{
  "message" : "The requested operation cannot be performed, because it has to be performed in a transaction. Ensure you are wrapping your operation in the appropriate transaction boilerplate and try again.",
  "exception" : "BridgeNotInTransactionException",
  "fullname" : "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge$BridgeNotInTransactionException",
  "stackTrace" : [ "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.assertInUnterminatedTransaction(ThreadToStatementContextBridge.java:72)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.getTopLevelTransactionBoundToThisThread(ThreadToStatementContextBridge.java:105)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.getKernelTransactionBoundToThisThread(ThreadToStatementContextBridge.java:113)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.get(ThreadToStatementContextBridge.java:65)", "org.neo4j.kernel.impl.factory.ClassicCoreSPI.currentStatement(ClassicCoreSPI.java:205)", "org.neo4j.kernel.impl.factory.GraphDatabaseFacade$$Lambda$76/46581122.get(Unknown Source)", "org.neo4j.kernel.impl.coreapi.StandardNodeActions.statement(StandardNodeActions.java:56)", "org.neo4j.kernel.impl.core.NodeProxy.getDegree(NodeProxy.java:702)", "com.github.denizco.datascience.neo4jplugin.Utils.outgoingDegree(Utils.java:12)", "java.lang.reflect.Method.invoke(Method.java:483)", "org.neo4j.server.plugins.PluginMethod.invoke(PluginMethod.java:61)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:158)", "org.neo4j.server.rest.web.ExtensionService.invokeNodeExtension(ExtensionService.java:325)", "org.neo4j.server.rest.web.ExtensionService.invokeNodeExtension(ExtensionService.java:184)", "java.lang.reflect.Method.invoke(Method.java:483)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:144)", "org.neo4j.server.rest.dbms.AuthorizationFilter.doFilter(AuthorizationFilter.java:121)", "org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)", "java.lang.Thread.run(Thread.java:745)" ],
  "errors" : [ {
    "code" : "Neo.ClientError.Request.TransactionRequired",
    "message" : "The requested operation cannot be performed, because it has to be performed in a transaction. Ensure you are wrapping your operation in the appropriate transaction boilerplate and try again."
  } ]
}

这里发生了什么?为什么我需要在交易中包裹我的电话,我该怎么做?有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

Neo4j中的任何操作(读或写)都需要进行交易。如果没有明确管理,唯一的例外graphDb.execute(cypherString)会在引擎盖下创建交易

所以将你的代码包装成:

try (Transaction tx=graphDb.beginTx()) {
   // do your stuff
   tx.success();
}

然而,使用“服务器插件”几乎是旧技术。在Neo4j 3.0中,黄金标准是使用程序并使用CALL从Cypher访问它们。