No transaction started in current thread 错误

No transaction started in current thread error

我有这段代码需要索引文档:

  @Override public Boolean index(String dir, String entityId, Double longitude, Double latitude)
      throws Exception {
    if (writer == null) {
      writer = DatabaseManagerImpl.getInstance().getIndexWriter(dir);
    }
    Document doc = new Document();
    doc.add(new StoredField("entityId", entityId));
    doc.add(new LatLonPoint("latlon", latitude, longitude));
    Geo3DPoint point = new Geo3DPoint("geo3d", latitude, longitude);
    doc.add(point);
    writer.addDocument(doc);
    return null;
  }

使用此索引编写器配置:

  public IndexWriter getIndexWriter(String dir) {
    ContextualEnvironment env = Environments.newContextualInstance(dir);
    ExodusDirectory exodusDirectory = new ExodusDirectory(env, VfsConfig.DEFAULT, StoreConfig.WITHOUT_DUPLICATES_WITH_PREFIXING, new ExodusDirectoryConfig());
    Analyzer analyzer = new StandardAnalyzer();
    IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
    iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
    IndexWriter writer = env.computeInTransaction(txn -> {
      try {
        return new IndexWriter(exodusDirectory, iwc);
      } catch (IOException e) {
        return null;
      }
    });
    return writer;
  }

并这样使用:

  public void testSearch() throws Exception {
    String environment = TestEnvironment.getEnvironment();
    LuceneIndexer luceneIndexer = LuceneIndexerImpl.getInstance();
    luceneIndexer.index(environment, "0-1", lon, lat);
    List<String> results = luceneIndexer.searchNeighbor(environment, lon, lat,
        10.0, null, 10);
    Assert.assertTrue(results.contains("0-1"));
  }

它抛出:

java.lang.IllegalStateException: No transaction started in current thread

at jetbrains.exodus.env.ContextualEnvironmentImpl.getAndCheckCurrentTransaction(ContextualEnvironmentImpl.java:51) at jetbrains.exodus.lucene.ExodusIndexOutput.(ExodusIndexOutput.kt:33) at jetbrains.exodus.lucene.ExodusDirectory.createOutput(ExodusDirectory.kt:67) at org.apache.lucene.store.LockValidatingDirectoryWrapper.createOutput(LockValidatingDirectoryWrapper.java:44) at org.apache.lucene.store.TrackingDirectoryWrapper.createOutput(TrackingDirectoryWrapper.java:43) at org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter.(CompressingStoredFieldsWriter.java:112) at org.apache.lucene.codecs.compressing.CompressingStoredFieldsFormat.fieldsWriter(CompressingStoredFieldsFormat.java:128) at org.apache.lucene.codecs.lucene50.Lucene50StoredFieldsFormat.fieldsWriter(Lucene50StoredFieldsFormat.java:183) at org.apache.lucene.index.StoredFieldsConsumer.initStoredFieldsWriter(StoredFieldsConsumer.java:39) at org.apache.lucene.index.StoredFieldsConsumer.startDocument(StoredFieldsConsumer.java:46) at org.apache.lucene.index.DefaultIndexingChain.startStoredFields(DefaultIndexingChain.java:355) at org.apache.lucene.index.DefaultIndexingChain.processDocument(DefaultIndexingChain.java:391) at org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:251) at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:494) at org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1609) at org.apache.lucene.index.IndexWriter.addDocument(IndexWriter.java:1228)

Xodus是一个事务型数据库,所以它需要一个事务来操作,读写都需要。 LuceneDirectory 需要创建一个 ContexualEnvironment,使用它来创建事务。