

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

# 冪等性
<a name="durable-execution-idempotency"></a>

耐用的 函數提供內建的冪等性，以便從執行名稱開始執行。當您提供執行名稱時，Lambda 會使用它來防止重複的執行，並啟用呼叫請求的安全重試。根據預設at-least-once執行語意 - 在重播期間，軟體開發套件會傳回檢查點結果，而不會重新執行已完成的步驟，但您的商業邏輯必須等冪，才能在完成之前處理潛在的重試。

**注意**  
Lambda 事件來源映射 (ESM) 不支援啟動時的冪等性。因此，每次叫用 （包括重試） 都會啟動新的耐久執行。若要使用事件來源映射確保等冪性執行，請在函數程式碼中實作等冪性邏輯，例如使用 [Powertools for AWS Lambda](https://docs.aws.amazon.com//powertools/)或使用一般 Lambda 函數做為代理 （分派器），以使用等冪性金鑰 （執行名稱參數） 叫用持久性函數。

## 執行名稱
<a name="durable-idempotency-execution-names"></a>

您可以在叫用耐用函數時提供執行名稱。執行名稱做為等冪性金鑰，可讓您安全地重試調用請求，而無需建立重複的執行。如果您未提供名稱，Lambda 會自動產生唯一的執行 ID。

執行名稱在您的帳戶和區域中必須是唯一的。當您使用已存在的執行名稱叫用函數時，Lambda 行為取決於現有執行的狀態以及承載是否相符。

## 冪等行為
<a name="durable-idempotency-behavior"></a>

下表說明 Lambda 如何處理調用請求，取決於您是否提供執行名稱、現有的執行狀態，以及承載是否相符：


| 案例 | 提供的名稱？ | 現有執行狀態 | 承載是否相同？ | Behavior (行為) | 
| --- | --- | --- | --- | --- | 
| 1 | 否 | N/A | N/A | 新的執行已開始：Lambda 會產生唯一的執行 ID，並啟動新的執行 | 
| 2 | 是 | 從未存在或保留過期 | N/A | 新的執行已開始：Lambda 使用提供的名稱啟動新的執行 | 
| 3 | 是 | 執行中 | 是 | 等冪啟動：Lambda 會傳回現有的執行資訊，而不會啟動重複的執行資訊。對於同步調用，這可做為重新連接至執行中的執行 | 
| 4 | 是 | 執行中 | 否 | 錯誤：Lambda 傳回DurableExecutionAlreadyExists錯誤，因為具有此名稱的執行已使用不同的承載執行 | 
| 5 | 是 | 關閉 （成功、失敗、停止或逾時） | 是 | 等冪啟動：Lambda 會傳回現有的執行資訊，而不啟動新的執行。傳回已關閉的執行結果 | 
| 6 | 是 | 關閉 （成功、失敗、停止或逾時） | 否 | 錯誤：Lambda 傳回DurableExecutionAlreadyExists錯誤，因為具有此名稱的執行已在不同的承載下完成 | 

**注意**  
案例 3 和 5 示範等冪行為，其中 Lambda 透過傳回現有的執行資訊而非建立重複項目，安全地處理重複的調用請求。

## 步驟冪等性
<a name="durable-idempotency-steps"></a>

根據預設at-least-once執行語意。當您的函數在等待、回呼或失敗後重播時，軟體開發套件會根據檢查點日誌檢查每個步驟。對於已完成的步驟，開發套件會傳回檢查點結果，而不會重新執行步驟邏輯。不過，如果步驟失敗或函數在步驟完成之前中斷，則該步驟可能會執行多次。

您在步驟中包裝的業務邏輯必須等冪，才能處理潛在的重試。使用等冪性金鑰，以確保付款或資料庫寫入等操作只會執行一次，即使步驟重試也一樣。

**範例：在步驟中使用等冪索引鍵**

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';
import { randomUUID } from 'crypto';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Generate idempotency key once
    const idempotencyKey = await context.step('generate-key', async () => {
      return randomUUID();
    });
    
    // Use idempotency key in payment API to prevent duplicate charges
    const payment = await context.step('process-payment', async () => {
      return paymentAPI.charge({
        amount: event.amount,
        idempotencyKey: idempotencyKey
      });
    });
    
    return { statusCode: 200, payment };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
import uuid

@durable_execution
def handler(event, context: DurableContext):
    # Generate idempotency key once
    idempotency_key = context.step(
        lambda _: str(uuid.uuid4()),
        name='generate-key'
    )
    
    # Use idempotency key in payment API to prevent duplicate charges
    payment = context.step(
        lambda _: payment_api.charge(
            amount=event['amount'],
            idempotency_key=idempotency_key
        ),
        name='process-payment'
    )
    
    return {'statusCode': 200, 'payment': payment}
```

------

您可以將執行模式設定為 ，將步驟設定為at-most-once的執行語意`AT_MOST_ONCE_PER_RETRY`。這可確保每次重試嘗試時，步驟最多執行一次，但如果函數在步驟完成之前中斷，則可能完全無法執行。

SDK 透過驗證該步驟名稱和順序在重播期間符合檢查點日誌，強制執行確定性重播。如果您的程式碼嘗試以不同的順序或以不同的名稱執行步驟，開發套件會擲回 `NonDeterministicExecutionError`。

**重播如何搭配已完成的步驟運作：**

1. 第一次叫用：函數執行步驟 A、建立檢查點，然後等待

1. 第二次調用 （等待後）：函數從頭開始重播，步驟 A 會立即傳回檢查點結果，而無需重新執行，然後繼續步驟 B

1. 第三次叫用 （在另一個等待之後）：函數從頭開始重播，步驟 A 和 B 會立即傳回檢查點結果，然後繼續步驟 C

此重播機制可確保已完成的步驟不會重新執行，但您的商業邏輯仍必須等冪才能在完成之前處理重試。