0

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 で実行されていますが、異なるスレッドがメモリを分離しているようです。

ここで何が間違っていますか?

4

2 に答える 2

0

私は問題に時間を費やし、最終的に解決策を見つけました。

Vert.x の頂点は、厳密に分離された環境を作成します。これにより、工場の 2 番目のバージョン (上記のコードを参照) が初期化されます。そして、2 番目のファクトリは、2 番目の Neo4j インスタンスを初期化しようとします。

解決策は、Neo4j コードを専用のストレージ バーティクルに分離し、イベント バスを介してそのバーティクルにアクセスするテスト コードを記述することでした。

于 2012-07-26T08:25:09.820 に答える
0

すべてのスレッドから 1 つの neo4j インスタンスのみを実行していると確信していますか? そうしないと、複数の neo4j インスタンスがストア ファイルのロックで競合します。Neo4j はスレッド セーフですが、同じストアで複数の埋め込みインスタンスを実行することはありません。スケーリングするには、高可用性セットアップを使用します。http://docs.neo4j.org/chunked/snapshot/ha.html を参照してください

于 2012-07-17T15:47:33.133 に答える