Neo4j返回事务错误

时间:2015-10-06 11:06:18

标签: neo4j amazon

我在亚马逊上安装了neo4j。

我使用远程执行cypher语句的neo4j-jdbc创建了客户端。

如果我运行neo4j-jdbc客户端本地来远程对抗amazon上的neo4j实例,一切都按预期工作。

然而,当我将neo4j-jdbc客户端应用程序上传到另一个实例时 amazon并执行我得到此异常的语句:

2015-10-06 10:59:59,609 ERROR [com.mycompany.wm.common.repo.Neo4jRepo] - <Error returning userId=33>
java.sql.SQLException: Error executing statement
    at org.neo4j.jdbc.internal.rest.TransactionalQueryExecutor.executeQuery(TransactionalQueryExecutor.java:224)
    at org.neo4j.jdbc.internal.Neo4jConnection.executeQuery(Neo4jConnection.java:370)
    at org.neo4j.jdbc.internal.Neo4jPreparedStatement.executeQuery(Neo4jPreparedStatement.java:48)
    at com.mycompany.wm.common.repo.Neo4jRepo.getfollowUsersByProximitySensors(Neo4jRepo.java:159)
    at com.mycompany.wm.core.dao.LocationServiceDaoImpl.getfollowUsersByProximitySensors(LocationServiceDaoImpl.java:79)
    at com.mycompany.wm.core.service.LocationServiceImpl.getfollowUsers(LocationServiceImpl.java:38)
    at com.mycompany.world_map_service.web.http.VertxHttpServerVerticle.getUsersLocation(VertxHttpServerVerticle.java:69)
    at com.mycompany.world_map_service.web.http.VertxHttpServerVerticle$$Lambda$30/984195839.handle(Unknown Source)
    at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:218)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:67)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:96)
    at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:61)
    at com.mycompany.world_map_service.web.http.VertxHttpServerVerticle$$Lambda$32/1901044330.handle(Unknown Source)
    at io.vertx.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:276)
    at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:391)
    at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:137)
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.lambda$createConnAndHandle$24(HttpServerImpl.java:539)
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler$$Lambda$55/521685526.run(Unknown Source)
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$15(ContextImpl.java:312)
    at io.vertx.core.impl.ContextImpl$$Lambda$11/1686783496.run(Unknown Source)
    at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:217)
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.createConnAndHandle(HttpServerImpl.java:537)
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:474)
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:425)
    at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:85)
    at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:124)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:244)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:110)
    at java.lang.Thread.run(Thread.java:745)
Caused by: Error executing statement (404) - {"results":[],"errors":[{"code":"Neo.ClientError.Transaction.UnknownId","message":"Unrecognized transaction id. Transaction may have timed out and been rolled back."}]}
    at org.restlet.resource.ClientResource.doError(ClientResource.java:612)
    at org.neo4j.jdbc.internal.rest.Resources$TransactionClientResource.doError(Resources.java:283)
    at org.restlet.resource.ClientResource.handleInbound(ClientResource.java:1202)
    at org.restlet.resource.ClientResource.handle(ClientResource.java:1069)
    at org.restlet.resource.ClientResource.handle(ClientResource.java:1044)
    at org.restlet.resource.ClientResource.post(ClientResource.java:1453)
    at org.neo4j.jdbc.internal.rest.TransactionalQueryExecutor.post(TransactionalQueryExecutor.java:98)
    at org.neo4j.jdbc.internal.rest.TransactionalQueryExecutor.begin(TransactionalQueryExecutor.java:76)
    at org.neo4j.jdbc.internal.rest.TransactionalQueryExecutor.executeQuery(TransactionalQueryExecutor.java:214)
    ... 38 more

neo4j-jdbc代码:

public class Neo4jRepo {
..

 @PostConstruct
    public void init() {
        logger.debug("Neo4jRepo, Init");
        try {
            String connectionString = "jdbc:neo4j://" + NEO4J_HOST + ":" + NEO4J_PORT;
            Class.forName("org.neo4j.jdbc.Driver");
            conn = DriverManager.getConnection(connectionString, new Properties());
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

...

运行此方法:

 public Set<UserDistanceDTO> getfollowUsers(String userIdInput, boolean includeHopes, follow_RELATIONSHIP_TYPE relationship_type) {
        String followExpression = "follow";
        if (includeHopes) {
            followExpression = "follow*1..3";
        }

        String relationshipTye;
        if (relationship_type.equals(follow_RELATIONSHIP_TYPE.OUTGOING)) {
            relationshipTye = "->";

        } else if (relationship_type.equals(follow_RELATIONSHIP_TYPE.INCOMING)) {
            relationshipTye = "<-";

        } else {
            relationshipTye = "-";
        }
        Set<UserDistanceDTO> userDistanceDTOs = null;
        try {
            userDistanceDTOs = new HashSet<>();

            String getUsersStatement =
                    "MATCH (user:" + LABEL_NAME + " {userId:{1}})-[r:" + followExpression + "]" + relationshipTye + "f " +
                            "WHERE f <> user " +
                            "RETURN DISTINCT (f.userId) as userId";
            final PreparedStatement ps = conn.prepareStatement(getUsersStatement);
            ps.setString(1, userIdInput);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                userDistanceDTOs.add(new UserDistanceDTO((String) rs.getObject("userId"), 0));
            }

        } catch (SQLException e) {
            e.printStackTrace();
            logger.error("Error returning userId=" + userIdInput, e);
        }
        return userDistanceDTOs;
    }

}

由于

1 个答案:

答案 0 :(得分:1)

您应该验证您的代码。

我认为你正在创建声明:

final PreparedStatement ps = conn.prepareStatement(getUsersStatement);

但你永远不会关闭它们。看起来TransasctionalQueryExecutor是有状态的,如果您不关闭语句,那么之前的事务元数据会泄漏到新事务中。

尝试在语句中使用try-with-resource语法。在你的案例中的例子:

try (final PreparedStatement ps = conn.prepareStatement(getUsersStatement)) {
    ps.setString(1, userIdInput);
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
        userDistanceDTOs.add(new UserDistanceDTO((String) rs.getObject("userId"), 0));
    } 
}

注意: neo4j-jdbc正在使用transaction Cypher HTTP endpoint。这是应该记住的事情。因为在创建新语句时,它会在服务器上创建新事务来检索它的id。并且,当您执行查询时,它会使用指定的事务ID调用API方法 事务数据库中也有超时。如果交易在n秒内未使用,交易将被关闭。