View a markdown version of this page

Bloqueio negativo com transações do DynamoDB - Amazon DynamoDB

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.