本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
含版本編號的樂觀鎖定
樂觀鎖定是一種策略,可在寫入時偵測衝突,而不是阻止衝突。每個項目都包含一個版本屬性,每次更新都會遞增。更新項目時,您會包含條件表達式,以檢查版本號碼是否符合應用程式上次讀取的值。如果另一個程序同時修改項目,則條件會失敗,且 DynamoDB 會傳回 ConditionalCheckFailedException。
何時使用樂觀鎖定
樂觀鎖定非常適合下列情況:
多個使用者或程序可能會更新相同的項目,但衝突不常發生。
重試失敗的寫入對您的應用程式來說並不昂貴。
您想要避免管理分散式鎖定的額外負荷和複雜性。
常見的範例包括電子商務庫存更新、協作編輯平台和金融交易記錄。
取捨
- 在高度爭用中重試額外負荷
在高並行環境中,衝突發生的可能性提高,可能造成更多重試與更高的寫入成本。
- 實作複雜度
將版本控制新增至項目和處理條件式檢查,會增加應用程式邏輯的複雜性。適用於 Java v2 的 AWS SDK 增強型用戶端透過
@DynamoDbVersionAttribute註釋提供內建支援,可自動為您管理版本編號。
模式設計
在每個項目中包含版本屬性。以下為簡單的結構設計:
分割區索引鍵 – 每個項目的唯一識別符 (例如
ItemId)。屬性:
ItemId– 項目的唯一識別碼。Version– 表示項目版本編號的整數。QuantityLeft– 項目的剩餘庫存。
首次建立項目時,Version 屬性會設為 1。每次更新時,版本編號會遞增 1。
| ItemID (分割區索引鍵) | 版本 | QuantityLeft |
|---|---|---|
| 香蕉 | 1 | 10 |
| Apples | 1 | 5 |
| 橘色 | 1 | 7 |
實作
若要實作樂觀鎖定,請遵循下列步驟:
-
讀取項目的當前版本。
def get_item(item_id): response = table.get_item(Key={'ItemID': item_id}) return response['Item'] item = get_item('Bananas') current_version = item['Version'] -
使用檢查版本編號的條件表達式更新項目。
def update_item(item_id, qty_bought, current_version): try: response = table.update_item( Key={'ItemID': item_id}, UpdateExpression="SET QuantityLeft = QuantityLeft - :qty, Version = :new_v", ConditionExpression="Version = :expected_v", ExpressionAttributeValues={ ':qty': qty_bought, ':new_v': current_version + 1, ':expected_v': current_version }, ReturnValues="UPDATED_NEW" ) return response except ClientError as e: if e.response['Error']['Code'] == 'ConditionalCheckFailedException': print("Version conflict: another process updated this item.") raise -
使用新讀取重試來處理衝突。
每次重試都需要額外的讀取,因此請限制重試的總數。
def update_with_retry(item_id, qty_bought, max_retries=3): for attempt in range(max_retries): item = get_item(item_id) try: return update_item(item_id, qty_bought, item['Version']) except ClientError as e: if e.response['Error']['Code'] != 'ConditionalCheckFailedException': raise print(f"Retry {attempt + 1}/{max_retries}") raise Exception("Update failed after maximum retries.")
對於 Java 應用程式,適用於 Java v2 的 AWS SDK 增強型用戶端透過 @DynamoDbVersionAttribute註釋提供內建的樂觀鎖定支援,該註釋會自動為您管理版本編號。
如需條件表達式的詳細資訊,請參閱 DynamoDB 條件表達式 CLI 範例。