繁体   English   中英

在Couchbase中调用删除文档(带分页)时的Spring数据“TimeoutException”

[英]Spring Data “TimeoutException” when calling delete documents (with pagination) in Couchbase

我们的Spring Boot应用程序使用Couchbase DB并使用Spring-Data访问它

要从存储桶中删除记录,我们在存储库中创建了以下方法:

Slice<Dog> deleteAllByOwnerIdAndName(String ownerId, String name, Pageable pageable);

我们还有相关的指标:

CREATE INDEX `dogs_by_ownerId_and_name_idx` ON `dogs`(`ownerId`,`name`) WHERE (`_class` = "com.example.Dog")

我们的代码在尝试删除元素时使用了分页:

 Slice<Dog> dogsSlice = null;
 Pageable pageable = PageRequest.of(0, 1000, Sort.by("id"));
 int pageCounter = 0;
 do {
   log.debug("Deleting page No. {} of dogs", pageCounter++);
   dogsSlice = dogsRepository.deleteAllByOwnerIdAndName("3243242", "Max", pageable);
 } while (dogsSlice.hasNext());

但是,我们获得Timeoutexceptioin次数太多了:

删除狗的第0页

osssTaskUtils $ LoggingErrorHandler:计划任务中发生意外错误。

org.springframework.data.couchbase.core.CouchbaseQueryExecutionException:由于以下n1ql错误,无法执行查询:{“msg”:“超出时间超过7.5秒”,“代码”:1080}在org.springframework.data.couchbase。 core.CouchbaseTemplate.findByN1QL(CouchbaseTemplate.java:458)〜[classes!/:5.1.40]在org.springframework.data.couchbase.repository.query.AbstractN1qlBasedQuery.executeSliced(AbstractN1qlBasedQuery.java:189)〜[classes!/ :org.springframework.data.couchbase.repository.query。 .AbstractN1qlBasedQuery.execute(AbstractN1qlBasedQuery.java:106)〜[classes!/:5.1.40]在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590)〜[classes! /:5.1.40]在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMeth odInterceptor.invoke(RepositoryFactorySupport.java:578)〜[classes!/:5.1.40] org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[classes!/:5.1.40] at at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)〜[classes!/:5.1.40] org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[classes !/:5.1.40] org.springframework.data.couchbase.repository.support.ViewPostProcessor $ ViewInterceptor.invoke(ViewPostProcessor.java:87)〜[classes!/:5.1.40] org.springframework.aop.framework .ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[classes!/:5.1.40] atg.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)〜[classes!/:5.1.40]在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) 〜[classes!/:5.1.40] org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)〜[classes!/:5.1.40] org.springframework.aop.framework.ReflectiveMethodInvocation。在org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)〜[classes!/:5.1.40]中继续(ReflectiveMethodInvocation.java:185)〜[classes!/:5.1.40]在Org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[classes!/:5.1.40] org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)〜 [classes!/:5.1.40] at com.sun.proxy。$ Proxy130.deleteAllByOwnerIdAndName(Unknown Source)〜[na:na]

还有什么我们需要做的吗?

你可以改进一些事情:

1)更改索引以按ownerId排序,然后在删除时,也按ownerId排序

CREATE INDEX `dogs_by_ownerId_and_name_idx` ON `dogs`(`ownerId` ASC,`name`) WHERE (`_class` = "com.example.Dog") 

由于您的索引已经排序,因此couchbase在删除过程中不会花费额外的时间对其进行排序。

2)你真的需要返回所有删除的对象吗? 在将文档发回给您之前,Couchbase必须提供索引中没有的所有属性,此操作将花费一些额外的时间。 最好的方法是只返回ID。

@Override
public void updateFamilyName(String familyName, String familyId) {

    String queryString = "Delete from "+getBucketName()+" WHERE "+getClassFilter()+" " +
            " and familyId = '"+familyId+"' RETURNING meta().id";

    N1qlParams params = N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS).adhoc(true);
    ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);
    checklistRepository.getCouchbaseOperations().getCouchbaseBucket().query(query);
}

private String getBucketName(){
    return checklistRepository.getCouchbaseOperations().getCouchbaseBucket().bucketManager().info().name();
}

private String getClassFilter(){
    return "_class = '" + Checklist.class.getName() + "' ";
}

3)你也可以改善你的分页,但我不认为你的情况是必要的。

https://blog.couchbase.com/offset-keyset-pagination-n1ql-query-couchbase/

Sort.by("id")导致查询延迟,因为看起来Couchbase正按照该标准对整个文档集进行排序。

因此,如果没有真正需要对结果进行排序,最好使用

Pageable pageable = PageRequest.of(0, 1000);

如果查询具有ORDER BY,则可能的优化器尝试使用索引顺序。 如果不可能,它必须生成所有可能的数据集并对数据进行排序以满足查询,甚至分页也需要很少的项目。

检查规则#7 https://blog.couchbase.com/create-right-index-get-right-performance/

另请参阅此文章https://blog.couchbase.com/offset-keyset-pagination-n1ql-query-couchbase/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM