使用 DynamoDB 交易進行估算鎖定 - Amazon DynamoDB

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

使用 DynamoDB 交易進行估算鎖定

DynamoDB 交易提供all-or-nothing方法。當您使用 時TransactWriteItems,DynamoDB 會監控交易中的所有項目。如果在交易期間由其他操作修改任何項目,則整個交易都會取消,且 DynamoDB 會傳回 TransactionCanceledException。這種行為提供一種可觀的並行控制形式,因為防止衝突並行修改,而不是在事實之後偵測到。

何時使用交易進行鎖定

在下列情況下,交易非常適合:

  • 您需要以原子方式更新多個項目,無論是在同一資料表內或跨資料表。

  • 您的商業邏輯需要all-or-nothing語意 - 所有變更都成功套用或不套用。

常見範例包括在帳戶之間轉移資金、下訂單同時更新庫存和訂單資料表,以及在遊戲中的玩家之間交換項目。

取捨

較高的寫入成本

對於高達 1 KB 的項目,相較於標準寫入的 1 WCUs,交易會耗用每個項目 2 個 WCU (一個用於準備,一個用於遞交)。

項目限制

單一交易最多可包含一或多個資料表中的 100 個動作。

衝突敏感度

如果交易中的任何項目被另一個操作修改,則整個交易會失敗。在高內容案例中,這可能會導致頻繁取消。

實作

下列範例使用 在兩個項目之間TransactWriteItems以原子方式傳輸庫存。如果另一個程序在交易期間修改任一項目,則會復原整個操作。

import boto3 client = boto3.client('dynamodb') def transfer_inventory(source_id, target_id, quantity): try: client.transact_write_items( TransactItems=[ { 'Update': { 'TableName': 'Inventory', 'Key': {'ItemID': {'S': source_id}}, 'UpdateExpression': 'SET QuantityLeft = QuantityLeft - :qty', 'ConditionExpression': 'QuantityLeft >= :qty', 'ExpressionAttributeValues': { ':qty': {'N': str(quantity)} } } }, { 'Update': { 'TableName': 'Inventory', 'Key': {'ItemID': {'S': target_id}}, 'UpdateExpression': 'SET QuantityLeft = QuantityLeft + :qty', 'ExpressionAttributeValues': { ':qty': {'N': str(quantity)} } } } ] ) return True except client.exceptions.TransactionCanceledException as e: print(f"Transaction canceled: {e}") return False

在此範例中,條件表達式會檢查是否存在足夠的庫存,但不需要版本屬性。如果準備和遞交階段之間的另一個操作修改了交易中的任何項目,DynamoDB 會自動取消交易。這就是提供樂觀並行控制的原因 – 交易本身會防止衝突並行修改。

注意

您可以將版本檢查新增為其他條件表達式,以結合交易與樂觀鎖定。這提供額外的保護層,但並非交易偵測衝突的必要條件。

如需詳細資訊,請參閱管理 DynamoDB 交易的複雜工作流程