Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring数据Solr@Transaction提交_Spring_Solr - Fatal编程技术网

Spring数据Solr@Transaction提交

Spring数据Solr@Transaction提交,spring,solr,Spring,Solr,我目前有一个设置,将数据插入数据库,并将其索引到Solr中。这两个步骤通过@transaction注释包装在spring管理的事务中。我注意到,每当事务关闭时,SpringDataSolr都会使用以下参数发出更新:params{commit=true&softCommit=false&waitSearcher=true} @Transactional public void save(Object toSave){ dbRepository.save(toSave); solrR

我目前有一个设置,将数据插入数据库,并将其索引到Solr中。这两个步骤通过@transaction注释包装在spring管理的事务中。我注意到,每当事务关闭时,SpringDataSolr都会使用以下参数发出更新:params{commit=true&softCommit=false&waitSearcher=true}

@Transactional
public void save(Object toSave){
    dbRepository.save(toSave);
    solrRepository.save(toSave);
}
提交到solr的速率相当高,因此理想情况下,我希望将数据发送到solr索引,并定期让solr自动提交。我在solrconfig.xml中设置了autoCommit(和autoSoftCommit),但由于spring data solr正在发送这些提交参数,因此每次都会执行硬提交


我知道我可以下拉到SolrTemplateAPI并手动发出提交,如果可能的话,我希望将solr repository.save调用保留在spring管理的事务中。有没有办法修改提交时发送给solr的参数

我做类似事情的方法是创建save方法的自定义存储库实现

存储库的接口:

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

脚注:自动提交(在我看来)在概念上与事务不兼容。自动提交是solr的承诺,它将尝试在特定的时间限制内开始将其写入磁盘。然而,很多事情可能会阻止这种情况的发生——及时的电源或硬件故障、文档和模式之间的错误等等。但是客户不会知道solr没有遵守承诺,当事务实际失败时,它将看到成功。

在org.springframework.data.solr.repository.support.simpleslrepository中插入IDE调试断点后,请单击此处:

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

我发现将我的代码包装为@Transactional(以及其他使框架能够以事务形式开始/结束代码的细节)并没有达到“ApacheSolr的Spring数据”所期望的效果。stacktrace显示了代码事务作用域的代理和事务拦截器类,但它还显示了框架使用自己的另一个代理和事务拦截器启动自己的嵌套事务。当框架退出其crudepository.save()方法my code调用时,提交到Solr的操作由框架的嵌套事务完成。它发生在我们的外部交易退出之前。因此,试图在最后以一次提交而不是每次保存一次提交的方式批处理多个保存是徒劳的。似乎,对于我代码中的这个区域,我必须使用SolrJ将我的实体保存(更新)到Solr,然后在“我的”事务退出后进行提交

如果使用SpringSolr,我发现使用SolrTemplatebean可以在向Solr索引添加数据时“批量”更新。通过使用bean for SolrTemplate,您可以使用“addBeans”方法,该方法将向索引中添加一个集合,直到事务结束才提交。在我的例子中,我开始使用solrClient.add(),并在每次保存后提交集合时,通过迭代将集合保存到索引中,耗时长达4小时。通过使用solrTemplate.addBeans(Collect),它只需1秒多的时间就可以完成,因为提交是在整个集合上进行的。以下是一段代码片段:

@Resource
SolrTemplate solrTemplate;

public void doReindexing(List<Image> images) {

    if (images != null) {

        /* CMSSolrImage is a class with @SolrDocument mappings.
         * the List<Image> images is a collection pulled from my database
         * I want indexed in Solr. 
         */
        List<CMSSolrImage> sImages = new ArrayList<CMSSolrImage>();
        
        for (Image image : images) {
            
            CMSSolrImage sImage = new CMSSolrImage(image);
            
            sImages.add(sImage);
            
        }
        
        solrTemplate.saveBeans(sImages);

    }

}
@Resource
SolrTemplate SolrTemplate;
公共无效数据索引(列表图像){
如果(图像!=null){
/*CMSSolrImage是一个具有@SolrDocument映射的类。
*列表图像是从我的数据库中提取的集合
*我要用Solr索引。
*/
List sImages=new ArrayList();
用于(图像:图像){
CMSSolrImage sImage=新的CMSSolrImage(图像);
添加(sImage);
}
saveBeans(sImages);
}
}
@Configuration
public class FooSolrConfig {

    @Bean
    public SolrOperations getFooSolrOperations(SolrClient solrClient) {
        return new SolrTemplate(solrClient, "foo");
    }
}
private void commitIfTransactionSynchronisationIsInactive() {
    if (!TransactionSynchronizationManager.isSynchronizationActive()) {
        this.solrOperations.commit(solrCollectionName);
    }
}
@Resource
SolrTemplate solrTemplate;

public void doReindexing(List<Image> images) {

    if (images != null) {

        /* CMSSolrImage is a class with @SolrDocument mappings.
         * the List<Image> images is a collection pulled from my database
         * I want indexed in Solr. 
         */
        List<CMSSolrImage> sImages = new ArrayList<CMSSolrImage>();
        
        for (Image image : images) {
            
            CMSSolrImage sImage = new CMSSolrImage(image);
            
            sImages.add(sImage);
            
        }
        
        solrTemplate.saveBeans(sImages);

    }

}