簡體   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