

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 DynamoDB 時發生錯誤
<a name="Programming.Errors"></a>

 本節說明執行時期錯誤和其處理方式。其中也會說明 Amazon DynamoDB 特有的錯誤訊息和程式碼。如需適用於所有 AWS 服務的常見錯誤清單，請參閱[存取管理](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html)

**Topics**
+ [錯誤元件](#Programming.Errors.Components)
+ [交易性錯誤](#Programming.Errors.TransactionalErrors)
+ [錯誤訊息和錯誤碼](#Programming.Errors.MessagesAndCodes)
+ [應用程式中的錯誤處理](#Programming.Errors.Handling)
+ [錯誤重試和指數退避](#Programming.Errors.RetryAndBackoff)
+ [批次操作和錯誤處理](#Programming.Errors.BatchOperations)

## 錯誤元件
<a name="Programming.Errors.Components"></a>

當您的程式傳送請求時，DynamoDB 會嘗試進行處理。如果請求成功，則 DynamoDB 會傳回 HTTP 成功狀態碼 (`200 OK`) 以及所請求操作的結果。

如果請求不成功，DynamoDB 會傳回錯誤。每個錯誤都會有三個元件：
+ HTTP 狀態碼 (例如 `400`)。
+ 例外狀況名稱 (例如 `ResourceNotFoundException`)。
+ 錯誤訊息 (例如 `Requested resource not found: Table: tablename not found`)。

 AWS SDKs 負責將錯誤傳播到您的應用程式，以便您可以採取適當的動作。例如，在 Java 程式中，您可以撰寫 `try-catch` 邏輯來處理 `ResourceNotFoundException`。

如果您不是使用 AWS SDK，則需要從 DynamoDB 剖析低階回應的內容。以下是這類回應的範例。

```
HTTP/1.1 400 Bad Request
x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG
Content-Type: application/x-amz-json-1.0
Content-Length: 240
Date: Thu, 15 Mar 2012 23:56:23 GMT

{"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",
"message":"Requested resource not found: Table: tablename not found"}
```

## 交易性錯誤
<a name="Programming.Errors.TransactionalErrors"></a>

如需有關交易性錯誤的資訊，請參閱 [DynamoDB 中的交易衝突處理](transaction-apis.md#transaction-conflict-handling)

## 錯誤訊息和錯誤碼
<a name="Programming.Errors.MessagesAndCodes"></a>

以下是 DynamoDB 依 HTTP 狀態碼進行分組並傳回的例外狀況清單。*確定要重試嗎？*為*是*，則可以重新提交相同的請求。*確定要重試嗎？*為*否*，則需要先修正使用者端上的問題，再提交新的請求。

### HTTP 狀態碼 400
<a name="Programming.Errors.MessagesAndCodes.http400"></a>

HTTP `400` 狀態碼指出請求發生問題，例如身分驗證失敗、遺失必要參數，或超過資料表的佈建輸送量。您必須先修正應用程式中的問題，再重新提交請求。

**AccessDeniedException **  
訊息：*Access denied.* (存取遭拒。)  
用戶端未正確地簽署請求。如果您使用的是 AWS 軟體開發套件，系統會自動為您簽署請求；如果不是，則請移至*AWS 一般參考*中的 [Signature 第 4 版簽署程序](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)。  
OK to retry? (確定要重試嗎？) 否

**ConditionalCheckFailedException**  
訊息：*The conditional request failed.* (條件式請求失敗。)  
您已指定評估為 false 的條件。例如，您可能已嘗試對項目執行條件式更新，但屬性的實際值不符合條件中的預期值。  
OK to retry? (確定要重試嗎？) 否

**IncompleteSignatureException**  
訊息：*The request signature does not conform to standards. (請求簽章不符合 AWS 標準。)*  
請求簽章未包含所有必要元件。如果您使用的是 AWS 開發套件，系統會自動為您簽署請求；否則，請前往 中的 [Signature 第 4 版簽署程序](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)*AWS 一般參考*。  
OK to retry? (確定要重試嗎？) 否

**ItemCollectionSizeLimitExceededException**  
訊息：*Collection size exceeded.* (已超過集合大小。)  
針對具有本機次要索引的資料表，具有相同分割區索引鍵值的項目群組已超過 10 GB 的大小上限。如需項目集合的詳細資訊，請參閱 [本機次要索引中的項目集合](LSI.md#LSI.ItemCollections)。  
OK to retry? (確定要重試嗎？) 是

**LimitExceededException**  
訊息：*Too many operations for a given subscriber.* (指定訂閱用戶的操作太多。)  
並行控制平面操作太多。在 `CREATING`、`DELETING` 或 `UPDATING` 狀態中，資料表和索引的累積數量不能超過 500。  
OK to retry? (確定要重試嗎？) 是

**MissingAuthenticationTokenException**  
訊息：*Request must contain a valid (registered) AWS Access Key ID. (請求必須包含有效 (已註冊) AWS 存取金鑰 ID。)*  
請求未包含必要授權標頭，或其格式不正確。請參閱 [DynamoDB 低階 API](Programming.LowLevelAPI.md)。  
OK to retry? (確定要重試嗎？) 否

**ProvisionedThroughputExceededException**  
訊息：*You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. To view performance metrics for provisioned throughput vs. consumed throughput, open the [Amazon CloudWatch console](https://console.aws.amazon.com/cloudwatch/home). (您已超過資料表或一或多個全域次要索引的最大允許佈建輸送量。若要檢視佈建輸送量與使用輸送的效能指標，請開啟 Amazon CloudWatch 主控台。)*  
錯誤包含 `ThrottlingReason` 欄位清單，提供為何發生限流的特定內容，並遵循格式 `ResourceType+OperationType+LimitType` (例如 `TableReadProvisionedThroughputExceeded`) 和受影響資源的 ARN。這可協助您識別要限流的資源 (資料表或索引)、觸發限流的操作類型 (讀取或寫入)，以及超過的特定限制 (在此案例中為佈建容量)。如需診斷和解決限流問題的詳細資訊，請參閱 [限流診斷](throttling-diagnosing-workflow.md)。  
範例：您的請求率太高。DynamoDB AWS SDKs 會自動重試收到此例外狀況的請求。除非您的重試佇列太大無法完成，否則您的請求最後會成功。請使用 [錯誤重試和指數退避](#Programming.Errors.RetryAndBackoff) 來減少請求的頻率。  
OK to retry? (確定要重試嗎？) 是

**ReplicatedWriteConflictException**  
訊息：*另一個區域中的請求正在修改此請求中的一或多個項目。*  
範例：針對多區域強式一致性 (MRSC) 全域資料表中的項目請求寫入操作，該資料表目前正由另一個區域中的請求修改。  
OK to retry? (確定要重試嗎？) 是

**RequestLimitExceeded**  
訊息：*輸送量超過帳戶的目前輸送量限制。若要請求提高限制，請聯絡 AWS Support，網址為 https：//[https://aws.amazon.com/support](https://aws.amazon.com/support)*。  
錯誤包含 `ThrottlingReason` 欄位清單，提供為何發生限流的特定內容，並遵循格式 `ResourceType+OperationType+LimitType` (例如 `TableWriteAccountLimitExceeded` 或 `IndexReadAccountLimitExceeded`) 和受影響資源的 ARN。這可協助您識別正在限流的資源 (資料表或索引)、觸發限流的操作類型 (讀取或寫入)，以及已超過帳戶層級的服務配額。如需診斷和解決限流問題的詳細資訊，請參閱 [限流診斷](throttling-diagnosing-workflow.md)。  
範例：隨選請求率超過允許的帳戶輸送量且資料表無法進一步擴展。  
OK to retry? (確定要重試嗎？) 是

**ResourceInUseException**  
訊息：*The resource which you are attempting to change is in use. *(正在使用您嘗試變更的資源。)  
範例：您已嘗試重新建立現在資料表，或刪除目前處於 `CREATING` 狀態的資料表。  
OK to retry? (確定要重試嗎？) 否

**ResourceNotFoundException **  
訊息：*Requested resource not found.* (找不到已註冊的資源。)  
範例：所請求的資料表不存在，或太早處於 `CREATING` 狀態。  
OK to retry? (確定要重試嗎？) 否

**ThrottlingException**  
訊息：*Rate of requests exceeds the allowed throughput.* (請求率超過允許的輸送量。)  
這個例外狀況會傳回為 AmazonServiceException 回應，並具備 THROTTLING\$1EXCEPTION 狀態碼。如果您執行[控制平面](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.ControlPlane) API 操作太快，可能會傳回此例外狀況。  
對於使用隨需的資料表，如果您的請求率太高，任何[資料平面](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.DataPlane) API 操作都可能會傳回此例外狀況。若要進一步了解隨需擴展，請參閱 [初始輸送量與擴展特性](on-demand-capacity-mode.md#on-demand-capacity-mode-initial)。  
錯誤包含 `ThrottlingReason` 欄位清單，提供為何發生限流的特定內容，並遵循格式 `ResourceType+OperationType+LimitType` (例如 `TableReadKeyRangeThroughputExceeded` 或 `IndexWriteMaxOnDemandThroughputExceeded`) 和受影響資源的 ARN。此資訊可協助您識別要限流的資源 (資料表或索引)、觸發限流的操作類型 (讀取或寫入)，以及超過的特定限制 (分割區限制或隨需最大輸送量)。如需診斷和解決限流問題的詳細資訊，請參閱 [限流診斷](throttling-diagnosing-workflow.md)。  
OK to retry? (確定要重試嗎？) 是

**UnrecognizedClientException**  
訊息：*The Access Key ID or security token is invalid.* (存取金鑰 ID 或安全字符無效。)  
請求簽章不正確。最可能的原因是無效的 AWS 存取金鑰 ID 或私密金鑰。  
OK to retry? (確定要重試嗎？) 是

**ValidationException**  
訊息：Varies, depending upon the specific error(s) encountered (會根據發生的特定錯誤而不同)  
可能會因數個原因而發生此錯誤，例如必要參數遺失、值超出範圍，或資料類型不符。錯誤訊息包含導致錯誤之請求特定部分的詳細資訊。  
OK to retry? (確定要重試嗎？) 否

### HTTP 狀態碼 5xx
<a name="Programming.Errors.MessagesAndCodes.http5xx"></a>

HTTP `5xx` 狀態碼指出 AWS必須解決的問題。這可能是暫時性錯誤，在此情況下，您可以重試請求，直到成功為止。如果不是，請前往 [AWS Service Health Dashboard](https://status.aws.amazon.com/)，確認服務是否發生任何操作問題。

如需詳細資訊，請參閱[如何解決 Amazon DynamoDB 中的 HTTP 5xx 錯誤？](https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-http-5xx-errors/)

**InternalServerError (HTTP 500)**  
DynamoDB 無法處理您的請求。  
OK to retry? (確定要重試嗎？) 是  
處理項目時，您可能會發生內部伺服器錯誤。在資料表生命週期期間，這些是預期錯誤。可以立即重試任何失敗的請求。  
當您在寫入作業上收到狀態碼 500 時，作業可能已成功或失敗。如果寫入操作是 `TransactWriteItem` 請求，則可以重試操作。如果寫入作業是單一項目寫入要求，例如 `PutItem`、`UpdateItem`，或 `DeleteItem`，那麼您的應用程序應該在重試操作之前讀取項目的狀態，和/或使用 [DynamoDB 條件表達式 CLI 範例](Expressions.ConditionExpressions.md)，以確保項目在重試後保持正確的狀態，無論先前的作業是成功還是失敗。如果冪等性是寫入操作的要求，請使用 [`TransactWriteItem`](transaction-apis.md#transaction-apis-txwriteitems)，它通過自動指定 `ClientRequestToken` 來消除多次嘗試執行相同動作的歧義。

**ServiceUnavailable (HTTP 503)**  
DynamoDB 目前無法使用。(這應該是暫時狀態)。  
OK to retry? (確定要重試嗎？) 是

## 應用程式中的錯誤處理
<a name="Programming.Errors.Handling"></a>

若要讓您的應用程式順暢執行，您需要新增邏輯來截獲並回應錯誤。一般方式包含使用 `try-catch` 區塊或 `if-then` 陳述式。

 AWS SDKs 會執行自己的重試和錯誤檢查。如果您在使用其中一個 AWS SDKs時發生錯誤，錯誤代碼和描述可協助您進行疑難排解。

您應該也會在回應中看到 `Request ID`。如果您需要與 AWS Support 合作來診斷問題， `Request ID`會很有幫助。

## 錯誤重試和指數退避
<a name="Programming.Errors.RetryAndBackoff"></a>

網路上有許多元件 (例如 DNS 伺服器、交換器、負載平衡器和其他項目) 可以在指定請求之生命週期中的任何階段產生錯誤。一般在網路環境中處理這些錯誤回應的技術，就是在用戶端應用程式中實作重試。這技術會提高應用程式的可靠性。

每個 AWS SDK 會自動實作重試邏輯。您可以視需要修改重試參數。例如，請考慮使用需要快速檢錯策略 (即發生錯誤時不允許重試) 的 Java 應用程式。透過 適用於 Java 的 AWS SDK，您可以使用 `ClientConfiguration`類別並提供 `maxErrorRetry`的值`0`來關閉重試。如需詳細資訊，請參閱程式設計語言的 AWS SDK 文件。

如果您不是使用 AWS SDK，您應該重試接收伺服器錯誤的原始請求 (5xx)。不過，用戶端錯誤 (4xx，非 `ThrottlingException` 或 `ProvisionedThroughputExceededException`) 指出您需要先修訂請求本身更正問題，然後再試一次。如需解決特定限流案例的詳細建議，請參閱 [DynamoDB 限流疑難排解](TroubleshootingThrottling.md)一節。

除了簡單的重試之外，每個 AWS SDK 還實作指數退避演算法，以更好地控制流程。指數退避的背後概念是，針對連續錯誤回應，讓重試之間的等待時間漸進拉長。例如，最多 50 毫秒再進行第一次重試、最多 100 毫秒再進行第二次重試、最多 200 毫秒再進行第三次重試，以此類推。不過，在一分鐘之後，如果請求未成功，則問題可能是請求大小超過佈建輸送量，而不是請求率。設定大約一分鐘停止的最大重試次數。如果請求未成功，請調查您的佈建輸送量選項。

**注意**  
 AWS SDKs 實作自動重試邏輯和指數退避。

大多數指數退避演算法會使用抖動 (隨機延遲)，以防止連續衝突。因為您在這些情況下並未嘗試避免這種衝突，所以不需要使用此亂數。不過，如果您使用並行用戶端，抖動有助於讓請求更快取得成功。如需詳細資訊，請參閱關於[指數退避和抖動](http://www.awsarchitectureblog.com/2015/03/backoff.html)的部落格文章。

## 批次操作和錯誤處理
<a name="Programming.Errors.BatchOperations"></a>

DynamoDB 低階 API 支援讀取和寫入的批次操作。`BatchGetItem` 從一或多個資料表讀取項目，`BatchWriteItem` 在一或多個資料表中放置或刪除項目。在其他非批次 DynamoDB 操作中，這些批次操作會實作為包裝函式。換言之，`BatchGetItem` 會針對批次中的每個項目調用 `GetItem` 一次。同樣地，`BatchWriteItem` 會針對批次中的每個項目適當地調用 `DeleteItem` 或 `PutItem`。

批次操作可以容忍批次中個別請求的失敗。例如，請考慮使用 `BatchGetItem` 請求來讀取五個項目。即使部分基礎 `GetItem` 請求失敗，這也不會導致整個 `BatchGetItem` 操作失敗。但若全部五個讀取操作均失敗，則整個 `BatchGetItem` 便會失敗。

批次操作會傳回失敗個別請求的資訊，讓您可以診斷問題，並重試操作。針對 `BatchGetItem`，會在回應的 `UnprocessedKeys` 值中傳回有問題的資料表和主索引鍵。針對 `BatchWriteItem`，在 `UnprocessedItems` 中會傳回類似的資訊。

最可能的失敗讀取或失敗寫入原因是*限流*。針對 `BatchGetItem`，批次請求中的一或多個資料表沒有足夠的已佈建讀取容量可支援操作。針對 `BatchWriteItem`，一或多個資料表沒有足夠的已佈建寫入容量。

如果 DynamoDB 傳回任何未處理的項目，您應該對這些項目重試批次操作。不過，*強烈建議您使用指數退避演算法*。如果您立即重試批次操作，則基於個別資料表上的限流，基礎讀取或寫入請求仍然可能會失敗。如果您使用指數退避來延遲批次操作，則批次中的個別請求較可能會成功。

**注意**  
 AWS SDKs提供更高層級的用戶端，可自動處理未處理的項目重試，因此您不需要自行實作此重試邏輯。例如：  
**Java** – 適用於 Java 的 AWS SDK v2 中的 [DynamoDB 增強型用戶端](DynamoDBEnhanced.md)和 v1 中的 [DynamoDBMapper](DynamoDBMapper.md) 都會在執行批次操作時自動重試未處理的項目。
**Python** – boto3 Table 資源會隱含地`batch_writer`處理未處理的項目重試，以進行批次寫入操作。如需詳細資訊，請參閱[使用資料表資源 batch\$1writer](programming-with-python.md#programming-with-python-batch-writer)。
如果您使用的是低階用戶端或不提供此行為的 SDK，您必須自行實作上述的重試邏輯。