Share via


針對 Azure Cosmos DB 找不到例外狀況進行診斷和疑難排解

適用於:NoSQL

HTTP 狀態碼 404 表示資源已不存在。

預期的行為

在許多有效的案例中,應用程式會預期狀態碼 404 並正確處理該案例。

針對應該存在或確實存在的項目,傳回了找不到的例外狀況

以下是如果項目應該存在或確實存在,會傳回狀態碼 404 的可能原因。

讀取工作階段不適用於輸入工作階段權杖

解決方案:

  1. 將您目前的 SDK 更新為可用的最新版本。 最新的 SDK 版本中已修正此特定錯誤的最常見原因。

競爭條件

有多個 SDK 用戶端執行個體,且讀取在寫入之前發生。

解決方案:

  1. Azure Cosmos DB 的預設帳戶一致性是工作階段一致性。 建立或更新項目時,回應會傳回可在 SDK 執行個體之間傳遞的工作階段權杖,以保證讀取要求會從具有該變更的複本讀取。
  2. 一致性層級變更為更強的層級

讀取容器或資料庫資源的輸送量

使用 PowerShell 或 Azure CLI,但收到找不到錯誤訊息。

解決方案:

您可以在資料庫層級、容器層級或兩者佈建輸送量。 如果收到找不到錯誤,請嘗試讀取父資料庫資源或子容器資源的輸送量。

無效的分割區索引鍵和識別碼組合

分割區索引鍵和識別碼組合無效。

解決方案:

修正會導致不正確組合的應用程式邏輯。

項目識別碼中有無效的字元

項目插入至 Azure Cosmos DB 中,並在項目識別碼中包含無效的字元

解決方案:

將識別碼變更為不包含特殊字元的其他值。 如果無法變更識別碼,您可以該識別碼使用 Base64 編碼,以逸出特殊字元。 Base64 仍可以產生具有無效字元 '/' 的名稱,必須加以取代。

已在該識別碼容器中插入的項目可以使用 RID 值 (而非以名稱為基礎的參考) 來取代。

// Get a container reference that uses RID values.
ContainerProperties containerProperties = await this.Container.ReadContainerAsync();
string[] selfLinkSegments = containerProperties.SelfLink.Split('/');
string databaseRid = selfLinkSegments[1];
string containerRid = selfLinkSegments[3];
Container containerByRid = this.cosmosClient.GetContainer(databaseRid, containerRid);

// Invalid characters are listed here.
// https://learn.microsoft.com/dotnet/api/microsoft.azure.documents.resource.id#remarks
FeedIterator<JObject> invalidItemsIterator = this.Container.GetItemQueryIterator<JObject>(
    @"select * from t where CONTAINS(t.id, ""/"") or CONTAINS(t.id, ""#"") or CONTAINS(t.id, ""?"") or CONTAINS(t.id, ""\\"") ");
while (invalidItemsIterator.HasMoreResults)
{
    foreach (JObject itemWithInvalidId in await invalidItemsIterator.ReadNextAsync())
    {
        // Choose a new ID that doesn't contain special characters.
        // If that isn't possible, then Base64 encode the ID to escape the special characters.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(itemWithInvalidId["id"].ToString());
        itemWithInvalidId["id"] = Convert.ToBase64String(plainTextBytes).Replace('/', '!');

        // Update the item with the new ID value by using the RID-based container reference.
        JObject item = await containerByRid.ReplaceItemAsync<JObject>(
            item: itemWithInvalidId,
            ID: itemWithInvalidId["_rid"].ToString(),
            partitionKey: new Cosmos.PartitionKey(itemWithInvalidId["status"].ToString()));

        // Validating the new ID can be read by using the original name-based container reference.
        await this.Container.ReadItemAsync<ToDoActivity>(
            item["id"].ToString(),
            new Cosmos.PartitionKey(item["status"].ToString())); ;
    }
}

存留時間清除

項目已設定存留時間 (TTL) 屬性。 已清除該項目,因為 TTL 屬性已過期。

解決方案:

變更 TTL 屬性以防止項目遭到清除。

延遲索引編製

延遲索引未趕上。

解決方案:

等候索引趕上或變更索引原則。

父資源已刪除

項目所在的資料庫或容器已刪除。

解決方案:

  1. 從備份還原父資源,或重新建立資源。
  2. 建立新的資源以取代已刪除的資源。

7.容器/集合名稱區分大小寫

容器/集合名稱在 Azure Cosmos DB 中區分大小寫。

解決方案:

連線到 Azure Cosmos DB 時,請務必使用確切的名稱。

下一步