如何强制Azure CosmosDB Java SDK读取最新数据?
问题描述
我将Cosmos容器的TTL设置为1秒以强制删除所有项,随后通过查询语句SELECT VALUE COUNT(1) from c确认所有项已删除,再恢复原TTL设置。但问题是,我通过Azure门户已看到项被删除,而SDK的查询却长时间返回旧的错误值。我尝试刷新客户端、数据库及容器对象,但无效果。请问是否有办法强制SDK读取后端的真实值,或建立全新连接等?
相关代码
// 我的客户端创建方式如下,设置ConsistencyLevel.STRONG会报错,因为该级别高于数据库的一致性级别 CosmosClient cosmosClient = new CosmosClientBuilder().endpoint(DATABASE_HOST) .key(DATABASE_KEY) .consistencyLevel(ConsistencyLevel.SESSION) .contentResponseOnWriteEnabled(true) .buildClient(); // 获取数据库 CosmosDatabase dataBase = cosmosClient.getDatabase(databaseName); return dataBase; // 获取容器 CosmosContainer container = theDatabase.getContainer(containerProps.getId()); // 更新TTL containerProps.setDefaultTimeToLiveInSeconds(1); container.replace(containerProps); Thread.sleep(1000); // 现在确认容器内容已删除 // 我尝试刷新客户端、数据库、容器对象,但没有效果 CosmosClient refreshedCosmosClient = createSyncCosmosClient(); CosmosDatabase refreshedDatabase = refreshedCosmosClient.getDatabase(DATABASE_NAME); CosmosContainer refreshedContainer = refreshedDatabase.getContainer(container.getId()); // 查询容器中的项数量 CosmosPagedIterable<JsonNode> countOfDocs = refreshedContainer.queryItems(CHECK_CONTAINER_EMPTY_QUERY, new CosmosQueryRequestOptions(), JsonNode.class); context.getLogger().info("wooooooooooooooooaaaa" + countOfDocs.toString()); // 这个值不是最新的,是旧值 JsonNode count = countOfDocs.iterator().next(); int numberOfDocuments = count.asInt();
解决方法
1. 利用会话令牌强制读取最新状态
执行容器TTL更新操作后,从响应中提取会话令牌,将其传入查询请求选项,确保SDK基于最新的会话状态读取数据,避免旧缓存干扰:
// 更新TTL并获取响应 CosmosContainerResponse replaceResponse = container.replace(containerProps); // 获取最新会话令牌 String sessionToken = replaceResponse.getSessionToken(); // 创建查询选项并设置会话令牌 CosmosQueryRequestOptions queryOptions = new CosmosQueryRequestOptions(); queryOptions.setSessionToken(sessionToken); // 使用带会话令牌的选项执行查询 CosmosPagedIterable<JsonNode> countOfDocs = refreshedContainer.queryItems(CHECK_CONTAINER_EMPTY_QUERY, queryOptions, JsonNode.class);
2. 强制查询扫描所有文档(绕过索引)
默认COUNT查询依赖索引,若索引更新存在延迟会返回旧值。开启扫描强制遍历所有文档,可获取真实计数:
CosmosQueryRequestOptions queryOptions = new CosmosQueryRequestOptions(); queryOptions.setEnableScanInQuery(true); CosmosPagedIterable<JsonNode> countOfDocs = refreshedContainer.queryItems(CHECK_CONTAINER_EMPTY_QUERY, queryOptions, JsonNode.class);
3. 延长等待时间或循环检查
TTL删除为异步操作,1秒等待可能不足以完成删除任务。可延长等待时间,或循环查询直到计数为0:
// 延长等待时间至3秒 Thread.sleep(3000); // 或者循环检查,最多重试5次 int numberOfDocuments = -1; int retryCount = 0; while (numberOfDocuments != 0 && retryCount < 5) { CosmosPagedIterable<JsonNode> countOfDocs = refreshedContainer.queryItems(CHECK_CONTAINER_EMPTY_QUERY, new CosmosQueryRequestOptions(), JsonNode.class); JsonNode count = countOfDocs.iterator().next(); numberOfDocuments = count.asInt(); if (numberOfDocuments != 0) { Thread.sleep(1000); retryCount++; } }
内容的提问来源于stack exchange,提问作者user1843591
相关产品推荐
相关产品推荐

