Java 如何在使用Neo4j 2.0 RC1批量提交节点时提高性能?
我很想知道这个程序(如下)是否可以改进以更快地执行。似乎,当我们有适当的约束时(90秒有约束,而1秒没有约束),很多时间都花在事务的关闭()上 以下是程序的输出:Java 如何在使用Neo4j 2.0 RC1批量提交节点时提高性能?,java,performance,neo4j,Java,Performance,Neo4j,我很想知道这个程序(如下)是否可以改进以更快地执行。似乎,当我们有适当的约束时(90秒有约束,而1秒没有约束),很多时间都花在事务的关闭()上 以下是程序的输出: 2013-12-05 14:30:20,399 [main] INFO net.ahm.graph.Lab - ############# WAVE 1 ############# 2013-12-05 14:30:20,399 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX
2013-12-05 14:30:20,399 [main] INFO net.ahm.graph.Lab - ############# WAVE 1 #############
2013-12-05 14:30:20,399 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-05 14:30:45,296 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 24897
2013-12-05 14:30:45,296 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-05 14:32:20,372 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 95076
2013-12-05 14:32:20,372 [main] INFO net.ahm.graph.Lab - ############# WAVE 2 #############
2013-12-05 14:32:20,372 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-05 14:32:47,168 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 26796
2013-12-05 14:32:47,168 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-05 14:34:16,040 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 88872
2013-12-05 14:34:16,040 [main] INFO net.ahm.graph.Lab - ############# WAVE 3 #############
2013-12-05 14:34:16,040 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-05 14:34:44,423 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 28383
2013-12-05 14:34:44,423 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-05 14:36:16,964 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 92541
2013-12-05 14:36:16,964 [main] INFO net.ahm.graph.Lab - ############# WAVE 4 #############
2013-12-05 14:36:16,964 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-05 14:36:43,376 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 26412
2013-12-05 14:36:43,376 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-05 14:38:13,156 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 89780
2013-12-05 14:38:13,156 [main] INFO net.ahm.graph.Lab - ############# WAVE 5 #############
2013-12-05 14:38:13,156 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-05 14:38:39,459 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 26303
2013-12-05 14:38:39,459 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-05 14:40:10,581 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 91122
2013-12-05 14:40:10,582 [Thread-5] INFO net.ahm.graph.Lab - ### GRAPHDB SHUTDOWNHOOK INVOKED !!!
以下是测试程序:
import java.io.File;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.neo4j.graphdb.DynamicLabel;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.schema.ConstraintDefinition;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.kernel.impl.util.FileUtils;
public class Lab {
private static final Logger LOG = Logger.getLogger(Lab.class);
public static void main(String[] args) throws Exception {
FileUtils.deleteRecursively(new File("graphdb"));
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder("graphdb")
.setConfig(GraphDatabaseSettings.use_memory_mapped_buffers, "true")
.setConfig(GraphDatabaseSettings.keep_logical_logs, "false").setConfig(GraphDatabaseSettings.query_cache_size, "1000")
.setConfig(GraphDatabaseSettings.relationship_grab_size, "1000").newGraphDatabase();
registerShutdownHook(graphDb);
try (Transaction tx = graphDb.beginTx()) {
Schema schema = graphDb.schema();
createConstraint(schema, "TEST", "COUNT");
tx.success();
}
int count = 0;
long time;
for (int i = 1; i <= 5; i++) {
LOG.info("############# WAVE " + i + " #############");
time = System.currentTimeMillis();
Transaction tx = graphDb.beginTx();
LOG.info("TIME TO BEGIN TX (m-sec): " + (System.currentTimeMillis() - time));
try {
time = System.currentTimeMillis();
for (int j = 1; j <= 10000; j++) {
count++;
Node n = graphDb.createNode(DynamicLabel.label("TEST"));
n.setProperty("COUNT", count);
}
LOG.info("TIME TO CREATE 10000 nodes (m-sec): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
tx.success();
LOG.info("TIME TO MARK SUCCESS (m-sec): " + (System.currentTimeMillis() - time));
} finally {
time = System.currentTimeMillis();
tx.close();
LOG.info("TIME TO COMMIT (m-sec): " + (System.currentTimeMillis() - time));
}
}
}
private static void createConstraint(Schema schema, String label, String propertyName) {
Iterator<ConstraintDefinition> constraints = schema.getConstraints(DynamicLabel.label(label)).iterator();
if (constraints == null || !constraints.hasNext()) {
try {
schema.constraintFor(DynamicLabel.label(label)).assertPropertyIsUnique(propertyName).create();
} catch (org.neo4j.graphdb.ConstraintViolationException ex) {
LOG.error("CONSTRAINT ALREADY DEFINED ON: " + label);
}
}
}
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LOG.info("### GRAPHDB SHUTDOWNHOOK INVOKED !!!");
graphDb.shutdown();
}
});
}
}
使用悲观锁定替换约束并执行我们自己的查找将节点创建时间增加到50秒。但提交时间不超过2秒。这(50+2)仍然比有约束的90+25秒要好得多 我应该采用这种方法吗? 输出:
2013-12-06 12:01:39,535 [main] INFO net.ahm.graph.Lab - ############# WAVE 1 #############
2013-12-06 12:01:39,544 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-06 12:02:30,505 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 50961
2013-12-06 12:02:30,505 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-06 12:02:33,020 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 2515
2013-12-06 12:02:33,020 [main] INFO net.ahm.graph.Lab - ############# WAVE 2 #############
2013-12-06 12:02:33,020 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-06 12:03:16,146 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 43126
2013-12-06 12:03:16,146 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-06 12:03:17,241 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 1095
2013-12-06 12:03:17,241 [main] INFO net.ahm.graph.Lab - ############# WAVE 3 #############
2013-12-06 12:03:17,241 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-06 12:04:00,194 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 42953
2013-12-06 12:04:00,194 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-06 12:04:01,019 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 825
2013-12-06 12:04:01,019 [main] INFO net.ahm.graph.Lab - ############# WAVE 4 #############
2013-12-06 12:04:01,019 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-06 12:04:45,073 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 44054
2013-12-06 12:04:45,073 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-06 12:04:45,932 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 859
2013-12-06 12:04:45,932 [main] INFO net.ahm.graph.Lab - ############# WAVE 5 #############
2013-12-06 12:04:45,932 [main] INFO net.ahm.graph.Lab - TIME TO BEGIN TX (m-sec): 0
2013-12-06 12:05:29,401 [main] INFO net.ahm.graph.Lab - TIME TO CREATE 10000 nodes (m-sec): 43468
2013-12-06 12:05:29,401 [main] INFO net.ahm.graph.Lab - TIME TO MARK SUCCESS (m-sec): 0
2013-12-06 12:05:30,182 [main] INFO net.ahm.graph.Lab - TIME TO COMMIT (m-sec): 781
2013-12-06 12:05:30,183 [Thread-4] INFO net.ahm.graph.Lab - ### GRAPHDB SHUTDOWNHOOK INVOKED !!!
源代码:
package net.ahm.graph;
import java.io.File;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.neo4j.graphdb.DynamicLabel;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.schema.ConstraintDefinition;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.kernel.impl.util.FileUtils;
public class Lab {
private static final String TEST_PROPERTY = "COUNT";
private static final String TEST_LABEL = "TEST";
private static final Logger LOG = Logger.getLogger(Lab.class);
private static Node lockNode = null;
public static void main(String[] args) throws Exception {
FileUtils.deleteRecursively(new File("graphdb"));
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder("graphdb")
.setConfig(GraphDatabaseSettings.use_memory_mapped_buffers, "true")
.setConfig(GraphDatabaseSettings.keep_logical_logs, "false").setConfig(GraphDatabaseSettings.query_cache_size, "1000")
.setConfig(GraphDatabaseSettings.relationship_grab_size, "1000").newGraphDatabase();
registerShutdownHook(graphDb);
/*
* try (Transaction tx = graphDb.beginTx()) {
* Schema schema = graphDb.schema();
* createConstraint(schema, "TEST", "COUNT");
* tx.success();
* }
*/
createIndex(TEST_LABEL, TEST_PROPERTY, graphDb);
int count = 0;
long time;
try (Transaction tx = graphDb.beginTx()) {
lockNode = graphDb.createNode(DynamicLabel.label("LOCKNODE"));
tx.success();
}
for (int i = 1; i <= 5; i++) {
LOG.info("############# WAVE " + i + " #############");
time = System.currentTimeMillis();
Transaction tx = graphDb.beginTx();
LOG.info("TIME TO BEGIN TX (m-sec): " + (System.currentTimeMillis() - time));
try {
time = System.currentTimeMillis();
for (int j = 1; j <= 10000; j++) {
count++;
if (findNode(TEST_LABEL, TEST_PROPERTY, count, graphDb) == null) {
tx.acquireWriteLock(lockNode);
if (findNode(TEST_LABEL, TEST_PROPERTY, count, graphDb) == null) {
Node n = graphDb.createNode(DynamicLabel.label(TEST_LABEL));
n.setProperty(TEST_PROPERTY, count);
} else {
LOG.error("NODE WITH PROPERTY ALREADY EXISTS: " + count);
}
} else {
LOG.error("NODE WITH PROPERTY ALREADY EXISTS: " + count);
}
}
LOG.info("TIME TO CREATE 10000 nodes (m-sec): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
tx.success();
LOG.info("TIME TO MARK SUCCESS (m-sec): " + (System.currentTimeMillis() - time));
} finally {
time = System.currentTimeMillis();
tx.close();
LOG.info("TIME TO COMMIT (m-sec): " + (System.currentTimeMillis() - time));
}
}
}
private static void createConstraint(Schema schema, String label, String propertyName) {
Iterator<ConstraintDefinition> constraints = schema.getConstraints(DynamicLabel.label(label)).iterator();
if (constraints == null || !constraints.hasNext()) {
try {
schema.constraintFor(DynamicLabel.label(label)).assertPropertyIsUnique(propertyName).create();
} catch (org.neo4j.graphdb.ConstraintViolationException ex) {
LOG.error("CONSTRAINT ALREADY DEFINED ON: " + label);
}
}
}
private static void createIndex(String label, String propertyName, GraphDatabaseService graphDb) {
IndexDefinition indexDefinition;
try (Transaction tx = graphDb.beginTx()) {
Schema schema = graphDb.schema();
indexDefinition = schema.indexFor(DynamicLabel.label(label)).on(propertyName).create();
tx.success();
}
try (Transaction tx = graphDb.beginTx()) {
Schema schema = graphDb.schema();
schema.awaitIndexOnline(indexDefinition, 10, TimeUnit.SECONDS);
tx.success();
}
}
private static Node findNode(String sLabel, String propertyName, Object propertyValue, GraphDatabaseService graphDb) {
if (propertyValue != null) {
Label label = DynamicLabel.label(sLabel);
ResourceIterable<Node> ri = graphDb.findNodesByLabelAndProperty(label, propertyName, propertyValue);
if (ri != null) {
try {
ResourceIterator<Node> iter = ri.iterator();
if (iter != null && iter.hasNext()) {
return iter.next();
}
} catch (Exception e) {
LOG.error("ERROR WHILE FINDING ID: " + propertyValue + " , LABEL: " + sLabel + " , PROPERTY: " + propertyName, e);
}
}
}
return null;
}
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LOG.info("### GRAPHDB SHUTDOWNHOOK INVOKED !!!");
graphDb.shutdown();
}
});
}
}
package net.ahm.graph;
导入java.io.File;
导入java.util.Iterator;
导入java.util.concurrent.TimeUnit;
导入org.apache.log4j.Logger;
导入org.neo4j.graphdb.DynamicLabel;
导入org.neo4j.graphdb.GraphDatabaseService;
导入org.neo4j.graphdb.Label;
导入org.neo4j.graphdb.Node;
导入org.neo4j.graphdb.ResourceIterable;
导入org.neo4j.graphdb.ResourceIterator;
导入org.neo4j.graphdb.Transaction;
导入org.neo4j.graphdb.factory.GraphDatabaseFactory;
导入org.neo4j.graphdb.factory.GraphDatabaseSettings;
导入org.neo4j.graphdb.schema.ConstraintDefinition;
导入org.neo4j.graphdb.schema.IndexDefinition;
导入org.neo4j.graphdb.schema.schema;
导入org.neo4j.kernel.impl.util.FileUtils;
公共班级实验室{
私有静态最终字符串测试\u PROPERTY=“COUNT”;
专用静态最终字符串测试\u LABEL=“TEST”;
私有静态最终记录器日志=Logger.getLogger(Lab.class);
私有静态节点lockNode=null;
公共静态void main(字符串[]args)引发异常{
递归删除(新文件(“graphdb”);
GraphDatabaseService graphDb=新GraphDatabaseFactory().newEmbeddedDatabaseBuilder(“graphDb”)
.setConfig(GraphDatabaseSettings.use_memory_mapped_buffers,“true”)
.setConfig(GraphDatabaseSettings.keep_logical_logs,“false”).setConfig(GraphDatabaseSettings.query_cache_size,“1000”)
.setConfig(GraphDatabaseSettings.relationship_grab_size,“1000”).newGraphDatabase();
寄存器SHUTDownhook(graphDb);
/*
*try(事务tx=graphDb.beginTx()){
*Schema Schema=graphDb.Schema();
*createConstraint(模式,“测试”,“计数”);
*成功();
* }
*/
createIndex(测试标签、测试属性、graphDb);
整数计数=0;
长时间;
try(事务tx=graphDb.beginTx()){
lockNode=graphDb.createNode(DynamicLabel.label(“lockNode”);
成功();
}
对于(int i=1;i我发现了问题,只是索引编写器刷新太频繁。请参阅提交用简单索引替换约束并在插入更改提交之前查找存在性()在保持插入时间几乎不变的情况下,将时间缩短到一秒。我应该转储约束还是进一步改进约束?我很想尝试一下。它是否进入稳定版本?不,它不是稳定版本。不幸的是,不是,但是如果你想的话,请使用该补丁进行测试并使用新值进行更新。请参阅我上面的答案。这太简单了2.0 GA进行此修复已晚,但2.0.1将包含此修复。谢谢Mattias,将屏息等待2.0.1。你是摇滚明星!!
package net.ahm.graph;
import java.io.File;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.neo4j.graphdb.DynamicLabel;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.schema.ConstraintDefinition;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.kernel.impl.util.FileUtils;
public class Lab {
private static final String TEST_PROPERTY = "COUNT";
private static final String TEST_LABEL = "TEST";
private static final Logger LOG = Logger.getLogger(Lab.class);
private static Node lockNode = null;
public static void main(String[] args) throws Exception {
FileUtils.deleteRecursively(new File("graphdb"));
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder("graphdb")
.setConfig(GraphDatabaseSettings.use_memory_mapped_buffers, "true")
.setConfig(GraphDatabaseSettings.keep_logical_logs, "false").setConfig(GraphDatabaseSettings.query_cache_size, "1000")
.setConfig(GraphDatabaseSettings.relationship_grab_size, "1000").newGraphDatabase();
registerShutdownHook(graphDb);
/*
* try (Transaction tx = graphDb.beginTx()) {
* Schema schema = graphDb.schema();
* createConstraint(schema, "TEST", "COUNT");
* tx.success();
* }
*/
createIndex(TEST_LABEL, TEST_PROPERTY, graphDb);
int count = 0;
long time;
try (Transaction tx = graphDb.beginTx()) {
lockNode = graphDb.createNode(DynamicLabel.label("LOCKNODE"));
tx.success();
}
for (int i = 1; i <= 5; i++) {
LOG.info("############# WAVE " + i + " #############");
time = System.currentTimeMillis();
Transaction tx = graphDb.beginTx();
LOG.info("TIME TO BEGIN TX (m-sec): " + (System.currentTimeMillis() - time));
try {
time = System.currentTimeMillis();
for (int j = 1; j <= 10000; j++) {
count++;
if (findNode(TEST_LABEL, TEST_PROPERTY, count, graphDb) == null) {
tx.acquireWriteLock(lockNode);
if (findNode(TEST_LABEL, TEST_PROPERTY, count, graphDb) == null) {
Node n = graphDb.createNode(DynamicLabel.label(TEST_LABEL));
n.setProperty(TEST_PROPERTY, count);
} else {
LOG.error("NODE WITH PROPERTY ALREADY EXISTS: " + count);
}
} else {
LOG.error("NODE WITH PROPERTY ALREADY EXISTS: " + count);
}
}
LOG.info("TIME TO CREATE 10000 nodes (m-sec): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
tx.success();
LOG.info("TIME TO MARK SUCCESS (m-sec): " + (System.currentTimeMillis() - time));
} finally {
time = System.currentTimeMillis();
tx.close();
LOG.info("TIME TO COMMIT (m-sec): " + (System.currentTimeMillis() - time));
}
}
}
private static void createConstraint(Schema schema, String label, String propertyName) {
Iterator<ConstraintDefinition> constraints = schema.getConstraints(DynamicLabel.label(label)).iterator();
if (constraints == null || !constraints.hasNext()) {
try {
schema.constraintFor(DynamicLabel.label(label)).assertPropertyIsUnique(propertyName).create();
} catch (org.neo4j.graphdb.ConstraintViolationException ex) {
LOG.error("CONSTRAINT ALREADY DEFINED ON: " + label);
}
}
}
private static void createIndex(String label, String propertyName, GraphDatabaseService graphDb) {
IndexDefinition indexDefinition;
try (Transaction tx = graphDb.beginTx()) {
Schema schema = graphDb.schema();
indexDefinition = schema.indexFor(DynamicLabel.label(label)).on(propertyName).create();
tx.success();
}
try (Transaction tx = graphDb.beginTx()) {
Schema schema = graphDb.schema();
schema.awaitIndexOnline(indexDefinition, 10, TimeUnit.SECONDS);
tx.success();
}
}
private static Node findNode(String sLabel, String propertyName, Object propertyValue, GraphDatabaseService graphDb) {
if (propertyValue != null) {
Label label = DynamicLabel.label(sLabel);
ResourceIterable<Node> ri = graphDb.findNodesByLabelAndProperty(label, propertyName, propertyValue);
if (ri != null) {
try {
ResourceIterator<Node> iter = ri.iterator();
if (iter != null && iter.hasNext()) {
return iter.next();
}
} catch (Exception e) {
LOG.error("ERROR WHILE FINDING ID: " + propertyValue + " , LABEL: " + sLabel + " , PROPERTY: " + propertyName, e);
}
}
}
return null;
}
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LOG.info("### GRAPHDB SHUTDOWNHOOK INVOKED !!!");
graphDb.shutdown();
}
});
}
}