2016-11-09 102 views
2

我目前有一个设置,其中数据插入到数据库中,并且索引到Solr中。这两个步骤通过@Transaction注释封装在Spring管理的事务中。我已经注意到的是,弹簧数据的Solr发出一个更新每当交易被关闭下列参数:PARAMS {提交=真正& softCommit =假& waitSearcher =真}Spring Data Solr @Transaction Commits

@Transactional 
public void save(Object toSave){ 
    dbRepository.save(toSave); 
    solrRepository.save(toSave); 
} 

的提交速度到solr是相当高的,所以理想情况下,我想发送数据到solr索引,并定期solr自动提交。我在我的solrconfig.xml中设置了autoCommit(和autoSoftCommit),但由于spring-data-solr正在发送这些提交参数,因此每次都会进行艰难的提交。

我知道我可以下载到SolrTemplate API并手动发出提交,如果可能的话,我想在spring-managed事务中保留solr repository.save调用。有没有办法修改发送给solr的参数?

回答

0

我做了类似的事情的方式是创建一个自定义存储库实现的保存方法。

接口库:

public interface FooRepository extends SolrCrudRepository<Foo, String>, FooRepositoryCustom { 
} 

界面自定义覆盖:

public interface FooRepositoryCustom { 
    public Foo save(Foo entity); 
    public Iterable<Foo> save(Iterable<Foo> entities); 
} 

定制覆盖的执行情况:

public class FooRepositoryImpl { 

    private SolrOperations solrOperations; 

    public SolrSampleRepositoryImpl(SolrOperations fooSolrOperations) { 
     this.solrOperations = fooSolrOperations; 
    } 

    @Override 
    public Foo save(Foo entity) { 
     Assert.notNull(entity, "Cannot save 'null' entity."); 
     registerTransactionSynchronisationIfSynchronisationActive(); 
     this.solrOperations.saveBean(entity, 1000); 
     commitIfTransactionSynchronisationIsInactive(); 
     return entity; 
    } 

    @Override 
    public Iterable<Foo> save(Iterable<Foo> entities) { 
     Assert.notNull(entities, "Cannot insert 'null' as a List."); 

     if (!(entities instanceof Collection<?>)) { 
      throw new InvalidDataAccessApiUsageException("Entities have to be inside a collection"); 
     } 

     registerTransactionSynchronisationIfSynchronisationActive(); 
     this.solrOperations.saveBeans((Collection<? extends T>) entities, 1000); 
     commitIfTransactionSynchronisationIsInactive(); 
     return entities; 
    } 

    private void registerTransactionSynchronisationIfSynchronisationActive() { 
     if (TransactionSynchronizationManager.isSynchronizationActive()) { 
      registerTransactionSynchronisationAdapter(); 
     } 
    } 

    private void registerTransactionSynchronisationAdapter() { 
     TransactionSynchronizationManager.registerSynchronization(SolrTransactionSynchronizationAdapterBuilder 
       .forOperations(this.solrOperations).withDefaultBehaviour()); 
    } 

    private void commitIfTransactionSynchronisationIsInactive() { 
     if (!TransactionSynchronizationManager.isSynchronizationActive()) { 
      this.solrOperations.commit(); 
     } 
    } 
} 

,你还需要提供一个SolrOperations正确的solr核心豆:

@Configuration 
public class FooSolrConfig { 

    @Bean 
    public SolrOperations getFooSolrOperations(SolrClient solrClient) { 
     return new SolrTemplate(solrClient, "foo"); 
    } 
} 

脚注:自动提交(在我的脑海中)概念上与交易不相容。自动提交是solr的承诺,它会尝试在特定的时间限制内开始将其写入磁盘。然而,很多事情可能会阻止实际发生的事情 - 及时的电源或硬件故障,文档和模式之间的错误等等。但客户不知道Solr未能遵守诺言,并且交易将在它实际上失败了。

相关问题