Neo4j 无常图数据库和模式索引创建

Neo4j impermanent graph database and schema index creation

我正在尝试 运行 以下代码段(使用 Neo4j v2.2.1 / 非永久图形数据库):

@BeforeClass
public static void prepareAll() {
    graphDB = new TestGraphDatabaseFactory().newImpermanentDatabase();
}

// [...]

try (Transaction tx = graphDB.beginTx()) {
    IndexDefinition definition = graphDB.schema()
        .indexFor(Labels.ARTIST)
        .on("name")
        .create();

    graphDB.schema().awaitIndexOnline(definition, XXX, TimeUnit.MILLISECONDS);
    // [...]
    tx.success();
}

无论我将 XXX 设置多高,总会抛出 IllegalStateException:

java.lang.IllegalStateException: Expected index to come online within a reasonable time.
    at org.neo4j.kernel.impl.coreapi.schema.SchemaImpl.awaitIndexOnline(SchemaImpl.java:172)
    at xxx.Exercise_3_Test.should_create_index_on_name(Exercise_3_Test.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:53)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

这是非永久图数据库特有的吗?

非常感谢您的帮助!

只需将索引创建和等待拆分为两个单独的事务:

try (Transaction tx = graphDB.beginTx()) {
    graphDB.schema().indexFor(Labels.ARTIST).on("name").create();
    tx.success();
}

try (Transaction tx = graphDB.beginTx()) {
    graphDB.schema().awaitIndexesOnline(XXX, TimeUnit.MILLISECONDS);
    tx.success();
}

直到事务 completed/committed 才创建索引,并且直到索引联机才将事务标记为完成,因此您陷入了死锁错误。

您还需要用 tx.success() 结束您的 try 块,以告诉数据库提交事务,而不是将其回滚。