Java 多线程环境中的Vert.x和Neo4j

Java 多线程环境中的Vert.x和Neo4j,java,cucumber,jruby,neo4j,vert.x,Java,Cucumber,Jruby,Neo4j,Vert.x,我尝试在JRuby环境中运行cucumber测试。我将cucumber rake任务配置为在同一JVM中的另一个线程中启动嵌入式Vert.x应用程序服务器。 在应用程序启动期间,将初始化Neo4j的嵌入式实例。 最后,cumber、Vert.x和Neo4j都在同一个JVM(tada!)中运行 在一些测试场景的末尾,我想检查一下certian数据是否已经放置在数据库中。既然Neo4j文件说 EmbeddedGraphDatabase实例可以在多个线程之间共享。但是请注意,不能创建指向同一数据库的多

我尝试在JRuby环境中运行cucumber测试。我将cucumber rake任务配置为在同一JVM中的另一个线程中启动嵌入式Vert.x应用程序服务器。 在应用程序启动期间,将初始化Neo4j的嵌入式实例。 最后,cumber、Vert.x和Neo4j都在同一个JVM(tada!)中运行

在一些测试场景的末尾,我想检查一下certian数据是否已经放置在数据库中。既然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;
    }
  }

}
它都在同一个JVM中运行,但不同的线程似乎有不同的内存


我做错了什么?

您确定您只从所有线程运行一个neo4j实例吗?否则,几个neo4j实例将在锁定存储文件方面发生冲突。Neo4j是线程安全的,但不是在同一个存储上执行多个嵌入式实例,为了扩展它,您可以使用高可用性设置,请参见

我花了一些时间研究这个问题,并最终找到了解决方案

Vert.x中的垂直线创建严格隔离的环境。这将导致初始化my factory的第二个版本(请参见上面的代码)。第二个工厂尝试初始化第二个Neo4j实例


解决方案是,将Neo4j代码分离成一个专用的垂直存储区,并编写测试代码,通过事件总线访问垂直存储区。

对不起,可能我在问题描述中遗漏了一些内容。我只想使用一个Neo4j实例。上面的代码应该确保每个路径只创建一个实例。问题是,此实例在线程之间不共享。运行代码的第二个线程找到一个空的
数据库
散列结构,并尝试创建第二个实例,最终导致锁定错误。所以我的问题是:为什么第二个线程不能访问这个
数据库
对象?Philipp,你不能在同一个存储中打开两个不同的嵌入式DB实例-第一个是锁定文件,因为它们是内存映射的等等。你想实现什么?Peter,正如我在最初的问题和对您答案的评论中所说的,我从来没有想过在同一个商店上创建第二个实例。问题是,一个实例没有在线程之间共享。同时,我认为这不是Neo4j或cucumber的问题。我想,我对Vertx、JRuby和JVM脚本环境的内部知识一般来说太少了。由于某些原因,我无法从另一个JRuby环境访问Neo4j实例。很好!想写一篇关于这个的短文吗?
NativeException: java.lang.IllegalStateException: Unable to lock store