在嵌入式neo4j中处理事务的最佳方法是什么?

kei*_*ric 3 neo4j

我刚开始使用Graph数据库,并且最好学习neo4j.我在应用程序(JSF Based)中运行了一个neo4j的嵌入式实例.该应用程序的用例主要是让我学习使用图形数据库的概念和难点,并帮助确定最佳方式(即嵌入式或独立式).但我的测试应用程序是一个非常基本的联系人应用程序,能够定义关系(即KNOWS,WORKS_WITH,WORKS_FOR等),并最终能够根据这些关系提出建议(即"你可能也知道").

到目前为止,我已经有了基本的crud操作,可以添加/删除关系.我的下一步将是实际开始遍历图表(我认为).但我目前遇到的问题是,一旦我与服务器的会话到期,我无法重新建立新会话而不会收到IllegalStateException错误,抱怨该商店当前正在使用.我认为这是因为我从未在neo4j实例上调用shutdown.因此,这让我认为我处理交易的方式都是错误的所以我希望有人可以纠正我的理解(或错误理解,视情况而定)我应该怎么做.

以下是我的助手类中的一些方法,用于处理Web客户端和neo4j之间的操作:

public class NeoNodeUtils {
private GraphDatabaseService graphDb;

public NeoNodeUtils() {
    setup();
}

public void setup() {
    GraphDatabaseFactory neoFactory = new GraphDatabaseFactory();
    setGraphDb(neoFactory.newEmbeddedDatabase("Morpheus"));
    registerShutdownHook();
}

public GraphDatabaseService getGraphDb() {
    return graphDb;
}

public void setGraphDb(GraphDatabaseService graphDb) {
    this.graphDb = graphDb;
}

public Node getNode(Long id) {
    Transaction tx = getGraphDb().beginTx();
    Node node = null;
    try {
        node = getGraphDb().getNodeById(id);
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public Node createNode() {
    Transaction tx = getGraphDb().beginTx();
    Node node = null;
    try {
        node = graphDb.createNode();
        System.out.println("new nodeId = " + node.getId());
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public Node addNodeProperty(Node node, String propertyName, Object propertyValue) {
    Transaction tx = getGraphDb().beginTx();
    try {
        node.setProperty(propertyName, propertyValue);
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public void shutDown() {
    graphDb.shutdown();
}

public void registerShutdownHook() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            graphDb.shutdown();
        }
    });
}
}
Run Code Online (Sandbox Code Playgroud)

每个辅助方法的结构与getNode(Long id)和createNode()的结构完全相同,当然有些方法有一些逻辑,但没有什么比这更复杂,因为我只想学习它.

所以,最后我的问题:
*这是处理这些交易的正确方法吗?或者,我应该实现某种类型的事务管理器?
*另外,我应该在每次交易后调用shutdown吗?
*也许这应该在客户端会话级别而不是应用程序级别处理?

此类保留在服务器内存中,直到服务器(http/jvm)重新启动(如果您熟悉jsf,applicationScope),因此在每次事务后调用shutdown似乎有点过分.

编辑:我实际上撕裂了下面的答案标记为被接受,因为他们都在某种程度上回答了我的问题.所以,如果你想知道为什么没有接受答案,那就是原因.

Mat*_*nné 5

不要将GraphDatabaseService视为SQLConnection或类似的东西,它是一个长期存在的实例并且经常停止它会消除从长期存在的这样的实例中获得的许多好处并且带来很多大的不必要的开销.

你不需要像这样调用tx.failure().一个简单的:

public Node createNode() {
    Transaction tx = getGraphDb().beginTx();
    try {
        Node node = graphDb.createNode();
        System.out.println("new nodeId = " + node.getId());
        tx.success();
        return node;
    } finally {
        tx.finish();
    }
}

很好,因为只有在调用success()时才会认为事务成功,否则将回滚.读取操作也不需要在事务中执行,因此:

public Node getNode(Long id) {
    return getGraphDb().getNodeById(id);
}

足够.

  • 请注意,在Neo4j 2中,``finish`不推荐使用`close`,它允许使用try-with-resources Java 7'语句. (2认同)