我刚开始使用图形数据库,并认为最好的学习方法是 neo4j。我有一个在应用程序中运行的嵌入式 neo4j 实例(基于 JSF)。该应用程序的用例主要是让我学习使用图形数据库的概念和陷阱,并帮助确定最佳方式(即嵌入式或独立)。但是我的测试应用程序是一个非常基本的联系人应用程序,它能够定义关系(即 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();
}
});
}
}
每个辅助方法的结构几乎都与 getNode(Long id) 和 createNode() 完全相同,当然有些有更多的逻辑,但没有什么很复杂,因为我只是想学习这个。
所以,最后我的问题是:
*这是处理这些交易的正确方法吗?或者,我应该实现某种类型的事务管理器吗?
* 另外,我应该在每笔交易后调用关机吗?
* 也许这应该在客户端会话级别而不是应用程序级别处理?
此类将保留在服务器内存中,直到服务器 (http/jvm) 重新启动(如果您熟悉 jsf、applicationScope),因此在每次事务后调用 shutdown 似乎有点过头了。
编辑:我实际上对下面哪个答案标记为已接受感到困惑,因为他们都在某种程度上回答了我的问题。因此,如果您想知道为什么答案不被接受,那就是原因。