使用reactive spring-data-couchbase出现Observable(viewRow)内容已释放报错如何解决
The content of this Observable (viewRow) is already released.
Subscribe earlier or tune the CouchbaseEnvironment#autoreleaseAfter()
你调用的getCouchbaseOperations().findByN1QL()是阻塞式API,底层返回RxJava的Observable热流对象,查询会在Observable创建时立即执行,查询结果产生后如果超过autoreleaseAfter(默认2000ms)未被订阅,Couchbase会自动释放结果缓冲区,就会触发上述报错。你通过ReactiveWrapperConverters转成Flux后没有立即订阅,等到实际触发订阅时已经过了自动释放时间,是问题的核心诱因。
优先改用响应式API
替换阻塞的getCouchbaseOperations()为getReactiveCouchbaseOperations(),其findByN1QL()方法直接返回冷流Flux,只有订阅时才会执行查询,完全规避提前释放问题,改造后的代码如下:default Flux<NonPrimitiveAsset> findAssetByParameters(StringBuilder whereClause) { WherePath selectFrom = N1qlUtils .createSelectFromForEntity(getReactiveCouchbaseOperations().getCouchbaseBucket().name()); Statement statement = selectFrom.where(whereClause.toString()); N1qlQuery query = N1qlQuery.simple(statement, N1qlParams.build()); return getReactiveCouchbaseOperations().findByN1QL(query, NonPrimitiveAsset.class); }临时调整自动释放超时时间
如果暂时无法切换响应式API,可以调大autoreleaseAfter参数的阈值,规避超时释放问题,该方案仅作为临时兜底,不建议长期使用,配置示例如下:@Bean public CouchbaseEnvironment couchbaseEnvironment() { return DefaultCouchbaseEnvironment.builder() .autoreleaseAfter(5000) // 单位为毫秒,可根据业务场景调整 // 其余原有配置保持不变 .build(); }优化调用链路耗时
尽量避免在获取Flux和触发订阅之间加入耗时的同步逻辑,缩短Observable创建到订阅的时间差,也能降低触发该问题的概率。
内容的提问来源于stack exchange,提问作者user13391764

