JRuby 環境でキュウリのテストを実行しようとしています。cucumber rake タスクを構成して、組み込みの Vert.x アプリケーション サーバーを別のスレッドで起動しますが、同じ JVM 内にあります。アプリケーションの起動時に、Neo4j の組み込みインスタンスが初期化されます。最後に、Cucumber、Vert.x、および Neo4j がすべて同じ JVM で実行されています (tada!)。
いくつかのテスト シナリオの最後に、特定のデータがデータベース ベースに配置されているかどうかを確認したいと思います。そして、Neo4jのドキュメントが言うので...
EmbeddedGraphDatabase インスタンスは、複数のスレッド間で共有できます。ただし、同じデータベースを指す複数のインスタンスを作成できないことに注意してください。
...初期化済みの Neo4j インスタンスを取得して、これらのチェックに使用しようとしています。それを実現するために、次のファクトリを作成しました。
public class ConcurrentGraphDatabaseFactory {
private static HashMap<String, GraphDatabaseService> databases = new HashMap<String, GraphDatabaseService>();
public static synchronized GraphDatabaseService getOrCreateDatabase(String path, String autoIndexFields) {
System.out.println("databases: " + databases.toString());
if (databases.containsKey(path)) {
return databases.get(path);
} else {
final GraphDatabaseService database = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(path).
setConfig(GraphDatabaseSettings.node_keys_indexable, autoIndexFields).
setConfig(GraphDatabaseSettings.node_auto_indexing, GraphDatabaseSetting.TRUE).
newGraphDatabase();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
database.shutdown();
}
});
databases.put(path, database);
return database;
}
}
}
このファクトリは、インスタンスごとにのみpath
初期化されるようにする必要があります。しかし、関数getOrCreateDatabase
が 2 回目にアクセスした場合、内部データベースHashMap
はまだ空です。これにより、コードは同じデータで 2 番目の Neo4j インスタンスを初期化し、次のエラーで失敗します。
NativeException: java.lang.IllegalStateException: Unable to lock store
すべて同じ JVM で実行されていますが、異なるスレッドがメモリを分離しているようです。
ここで何が間違っていますか?