Bloqueio negativo com transações do DynamoDB
As transações do DynamoDB oferecem uma abordagem de tudo ou nada para operações agrupadas. Quando você usa TransactWriteItems, o DynamoDB monitora todos os itens na transação. Se algum item for modificado por outra operação durante a transação, toda a transação será cancelada e o DynamoDB exibirá uma TransactionCanceledException. Esse comportamento oferece uma forma de controle de simultaneidade negativo porque modificações simultâneas conflitantes são evitadas em vez de detectadas assim que ocorrem.
Quando usar transações para bloqueio
As transações são uma boa opção quando:
É necessário atualizar vários itens atomicamente, dentro da mesma tabela ou entre tabelas.
A lógica de negócios exige uma semântica de tudo ou nada: ou todas as alterações têm êxito ou nenhuma é aplicada.
Exemplos comuns incluem transferir fundos entre contas, fazer pedidos que atualizem o inventário e as tabelas de pedidos e trocar itens entre jogadores em um jogo.
Desvantagens
- Custo de gravação mais alto
Para itens de até 1 KB, as transações consomem 2 WCUs por item (uma para preparar e outra para confirmar), em comparação com 1 WCU para uma gravação padrão.
- Limite de itens
Uma única transação pode incluir até cem ações em uma ou mais tabelas.
- Sensibilidade a conflitos
Se algum item for modificado por outra operação, toda a transação falhará. Em cenários de alta contenção, isso pode levar a cancelamentos frequentes.
Implementação
O exemplo a seguir usa TransactWriteItems para transferir inventário entre dois itens atomicamente. Se outro processo modificar qualquer item durante a transação, toda a operação será revertida.
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
Neste exemplo, a expressão de condição verifica se existe inventário suficiente, mas nenhum atributo de versão é necessário. O DynamoDB cancelará automaticamente a transação se algum item da transação for modificado por outra operação entre as fases de preparação e confirmação. É isso que oferece o controle de simultaneidade negativo: modificações simultâneas conflitantes são evitadas pela própria transação.
nota
É possível associar transações com bloqueio positivo adicionando verificações de versão como expressões de condição adicionais. Isso oferece um nível extra de proteção, mas não é necessário para que a transação detecte conflitos.
Para obter mais informações, consulte Gerenciar fluxos de trabalho complexos com transações do DynamoDB.