Amazon DynamoDB Transactions: como funciona - Amazon DynamoDB

Amazon DynamoDB Transactions: como funciona

Com as Amazon DynamoDB Transactions, você pode agrupar várias ações juntas e enviá-las como uma única operação tudo ou nada TransactWriteItems ou TransactGetItems. As seções a seguir descrevem operações de API, gerenciamento de capacidade, práticas recomendadas e outros detalhes sobre o uso de operações transacionais no DynamoDB.

API TransactWriteItems

TransactWriteItems é uma operação de gravação síncrona e idempotente que agrupa até 100 ações de gravação em uma única operação tudo ou nada. Essas ações podem ter como destino até 100 itens distintos em uma ou mais tabelas do DynamoDB na mesma conta e região da AWS. O tamanho agregado dos itens na transação não podem exceder 4 MB. As ações são concluídas de forma atômica para que todas sejam bem-sucedidas ou nenhuma tenha êxito.

nota
  • Uma operação TransactWriteItems difere de uma operação BatchWriteItem em que todas as ações contidas devem ser concluídas com êxito, ou nenhuma alteração foi feita. Com uma operação BatchWriteItem, é possível que apenas as ações no lote sejam bem-sucedidas enquanto as outras não.

  • As transações não podem ser realizadas usando índices.

Você não pode visar o mesmo item com várias operações dentro da mesma transação. Por exemplo, você não pode executar uma ação ConditionCheck e também uma Update no mesmo item na mesma transação.

Você pode adicionar os tipos a seguir de ações a uma transação:

  • Put: inicia uma operação PutItem para criar um novo item ou substituir um item antigo com um item novo, de forma condicional ou sem especificar qualquer condição.

  • Update: inicia uma operação UpdateItem para editar um atributo de item existente ou adicionar um novo item à tabela se ele já não existir. Use essa ação para adicionar, excluir ou atualizar atributos ou um item existente de forma condicional ou sem uma condição.

  • Delete: inicia uma operação DeleteItem para excluir um único item em uma tabela identificada por essa chave principal.

  • ConditionCheck: verifica se um item existe ou verifica a condição de atributos específicos do item.

Quando uma transação é concluída, as alterações feitas com essa transação são propagadas para índices secundários globais (GSIs), streams e backups. Como a propagação não é imediata ou instantânea, se uma tabela for restaurada do backup (RestoreTableFromBackup) ou exportada para um ponto anterior no tempo (ExportTableToPointInTime) no meio da transação, ela poderá conter algumas, mas não todas as alterações feitas durante uma transação recente.

Potência igual

Você pode, opcionalmente, incluir um token de cliente quando fizer uma chamada TransactWriteItems para garantir que a solicitação é idempotente. Realizar transações idempotentes ajuda a prevenir erros de aplicação se a mesma operação for enviada diversas vezes por conta de uma desconexão ou outro problema de conexão.

Se a chamada TransactWriteItems original for bem-sucedida, as chamadas TransactWriteItems subsequentes com o mesmo token de cliente retornarão com êxito sem nenhuma alteração. Se o parâmetro ReturnConsumedCapacity estiver definido, a chamada TransactWriteItems inicial retornará o número de unidades de capacidade de gravação consumidas para realizar as alterações. Chamadas TransactWriteItems subsequentes com o mesmo token de cliente devolvem o número de unidades de capacidade de leitura consumidas na leitura do item.

Pontos importantes sobre idempotência
  • Um token de cliente é válido por 10 minutos após a solicitação utilizada acabar. Depois de 10 minutos, quaisquer solicitações que usarem o mesmo token de cliente são tratadas como uma nova solicitação. Você não deve reutilizar o mesmo token de cliente para a mesma solicitação após 10 minutos.

  • Se você repetir uma solicitação com o mesmo token de cliente dentro de 10 minutos na janela de idempotência, mas alterar algum parâmetro de solicitação, o DynamoDB retornará uma exceção IdempotentParameterMismatch.

Tratamento de erros para gravação

Transações de gravação não são bem-sucedidas nas circunstâncias a seguir:

  • Quando uma condição em uma das expressões de condição não é alcançada.

  • Quando uma validação de transação ocorrer por conta de mais de uma ação na mesma operação TransactWriteItems ter como destino o mesmo item.

  • Quando uma solicitação TransactWriteItems entra em conflito com uma operação TransactWriteItems em andamento em um ou mais itens na operação TransactWriteItems. Nesse caso, a solicitação falha com um TransactionCanceledException.

  • Quando há capacidade provisionada insuficiente para a transação ser concluída.

  • Quando o tamanho de um item é muito maior (maior que 400 KB), ou um índice secundário local (LSI) se torna muito grande, ou um erro de validação semelhante ocorre por conta das alterações feitas pela transação.

  • Quando houver um erro de usuário, como formato de dados inválidos.

Para obter mais informações sobre como os conflitos com operações TransactWriteItems são gerenciados, consulte Tratamento de conflitos em transações com o DynamoDB.

API TransactGetItems

TransactGetItems é uma operação de leitura síncrona que agrupa até 100 ações Get. Essas ações podem ter como destino até 100 itens distintos em uma ou mais tabelas do DynamoDB na mesma conta e região da AWS. O tamanho agregado dos itens na transação não pode exceder 4 MB.

As ações Get são realizadas de forma atômica para que todas sejam bem-sucedidas ou nenhuma tenha êxito:

  • Get: inicia uma operação GetItem para recuperar um conjunto de atributos do item com a chave primária fornecida. Se não houver item correspondente, Get não retornará quaisquer dados.

Tratamento de erros para leitura

Transações de leitura não são bem-sucedidas nas circunstâncias a seguir:

  • Quando uma solicitação TransactGetItems entra em conflito com uma operação TransactWriteItems em andamento em um ou mais itens na operação TransactGetItems. Nesse caso, a solicitação falha com um TransactionCanceledException.

  • Quando há capacidade provisionada insuficiente para a transação ser concluída.

  • Quando houver um erro de usuário, como formato de dados inválidos.

Para obter mais informações sobre como os conflitos com operações TransactGetItems são gerenciados, consulte Tratamento de conflitos em transações com o DynamoDB.

Níveis de isolamento para transações do DynamoDB

Os níveis de isolamento de operações transacionais (TransactWriteItems ou TransactGetItems) e outras operações são os seguintes.

SERIALIZÁVEL

Isolamento Serializável garante que os resultados de várias operações concomitantes sejam os mesmos como se nenhuma operação começar com o anterior finalizado.

Há um isolamento serializável entre os tipos a seguir de operação:

  • Entre qualquer operação transacional e qualquer padrão de operação de gravação (PutItem, UpdateItem ou DeleteItem).

  • Entre qualquer operação transacional e qualquer padrão de operação de leitura (GetItem).

  • Entre uma operação TransactWriteItems e TransactGetItems.

Apesar de haver isolamento serializável entre operações transacionais, e cada padrão individual de gravação em uma operação BatchWriteItem, não há isolamento serializável entre a transação e a operação BatchWriteItem como uma unidade.

De modo semelhante, o nível de isolamento entre uma operação transacional e GetItems individual em uma operação BatchGetItem é serializável. Porém, o nível de isolamento entre a transação e a operação BatchGetItem como uma unidade é confirmado para leitura.

Uma única solicitação GetItem é serializável em relação a uma solicitação TransactWriteItems de duas formas, antes ou depois da solicitação TransactWriteItems. Várias solicitações GetItem, contra chaves em solicitações TransactWriteItems, podem ser executadas em qualquer ordem e, portanto, os resultados são confirmado para leitura.

Por exemplo, se solicitações GetItem para o item A e o item B forem executadas simultaneamente com uma solicitação TransactWriteItems que modifica o item A e o item B, existem quatro possibilidades:

  • Ambas as solicitações GetItem são executadas antes da solicitação TransactWriteItems.

  • Ambas as solicitações GetItem são executadas após a solicitação TransactWriteItems.

  • A solicitação GetItem para o item A é executada antes da solicitação TransactWriteItems. Para o item B, GetItem é executada após TransactWriteItems.

  • A solicitação GetItem para o item B é executada antes da solicitação TransactWriteItems. Para o item A, GetItem é executada após TransactWriteItems.

Você deverá usar TransactGetItems se preferir o nível de isolamento serializável para várias solicitações GetItem.

Se uma leitura não transacional for feita em vários itens que faziam parte da mesma solicitação de gravação de transação em andamento, é possível que você consiga ler o novo estado de alguns dos itens e o estado antigo dos outros itens. Você poderá ler o novo estado de todos os itens que faziam parte da solicitação de gravação da transação somente quando uma resposta bem-sucedida for recebida para a gravação transacional.

CONFIRMADO PARA LEITURA

O isolamento confirmado para leitura garante que as operações de leitura sempre retornem valores confirmados para um item; a leitura nunca apresentará uma visualização do item representando um estado de uma gravação transacional que não teve êxito final. Isolamento confirmado para leitura não previne modificações do item imediatamente após operação de leitura.

O nível de isolamento é confirmado para leitura entre qualquer operação transacional e qualquer operação de leitura que envolva vários padrões de leitura (BatchGetItem, Query ou Scan). Se uma gravação transacional atualizar um item no meio de uma operação de BatchGetItem, Query ou Scan, a parte subsequente da operação de leitura retornará o novo valor confirmado [com ConsistentRead) ou possivelmente um valor confirmado anteriormente (leitura final consistente)].

Resumo da operação

Para resumir, a tabela a seguir mostra os níveis de isolamento entre uma operação transacional (TransactWriteItems ou TransactGetItems) e outras operações.

Operation Nível de isolamento

DeleteItem

Serializável

PutItem

Serializável

UpdateItem

Serializável

GetItem

Serializável

BatchGetItem

Confirmado para leitura*

BatchWriteItem

NÃO serializável*

Query

Confirmado para leitura

Scan

Confirmado para leitura

Outra operação transacional

Serializável

Níveis marcados com asterisco (*) aplicam-se à operação como uma unidade. No entanto, ações individuais dentro dessas operações tem um nível de isolamento serializável.

Tratamento de conflitos em transações com o DynamoDB

Um conflito de transação pode correr em solicitações simultâneas no nível do item, em um item dentro de uma transação. Os conflitos de transação podem ocorrer nos seguintes casos:

  • Uma solicitação PutItem, UpdateItem ou DeleteItem de um item conflita com uma solicitação TransactWriteItems em andamento que inclui o mesmo item.

  • Um item dentro de uma solicitação TransactWriteItems é parte de outra solicitação TransactWriteItems em andamento.

  • Um item dentro de uma solicitação TransactGetItems é parte de outra solicitação TransactWriteItems, BatchWriteItem, PutItem, UpdateItem ou DeleteItem em andamento.

nota
  • Quando uma solicitação PutItem, UpdateItem ou DeleteItem é rejeitada, a solicitação falha com um TransactionConflictException,

  • Se qualquer solicitação no nível do item dentro de TransactWriteItems ou TransactGetItems é rejeitada, a solicitação falha com um TransactionCanceledException. Se essa solicitação falhar, os AWS SDKs não tentarão repetir a solicitação.

    Se você estiver usando AWS SDK for Java, a exceção conterá a lista de CancellationReasons, em ordem de acordo com a lista de itens no parâmetro de solicitação TransactItems. Para outros idiomas, uma representação em string da lista é incluída na mensagem de erro de exceção.

  • Se uma operação TransactWriteItems ou TransactGetItems em andamento entrar em conflito com uma solicitação GetItem simultânea, as duas podem ter êxito.

A métrica TransactionConflict do CloudWatch é incrementada em cada solicitação que falhou no nível do item

Usar APIs transacionais no DynamoDB Accelerator (DAX)

O DynamoDB Accelerator (DAX) oferece suporte a TransactWriteItems e TransactGetItems com os mesmos níveis de isolamento que no DynamoDB.

TransactWriteItems grava via DAX. O DAX passa uma chamada TransactWriteItems para o DynamoDB e retorna a resposta. Para preencher o cache após a gravação, o DAX chama TransactGetItems em segundo plano para cada item na operação TransactWriteItems, o que consome unidades de capacidade de leitura adicionais. (Para ter mais informações, consulte Gerenciar capacidade para transações.) Essa funcionalidade permite manter simples a lógica da aplicação e usar o DAX para operações transacionais e não transacionais.

Chamadas de TransactGetItems são transmitidas pelo DAX sem que os itens sejam armazenados em cache localmente. É o mesmo comportamento para APIs de leitura fortemente consistente no DAX.

Gerenciar capacidade para transações

Não há custo adicional para habilitar transações para suas tabelas do DynamoDB. Você paga apenas pelas leituras ou gravações que fazem parte de sua transação. O DynamoDB realiza duas leituras subjacentes ou gravações de cada item na transação: uma para preparar a transação e outra para enviar a transação. Essas duas operações de leitura/gravação subjacente são visíveis nas métricas do Amazon CloudWatch.

Planeje para leituras e gravações adicionais que são necessárias por APIs transacionais ao provisionar a capacidade de suas tabelas. Por exemplo, suponha que sua aplicação execute uma transação por segundo e cada transação grave itens de 500 bytes em sua tabela. Cada item requer duas capacidades de gravação (WCUs): uma para preparar a transação e uma para enviar a transação. Portanto, você precisa provisionar seis WCUs na tabela.

Se você usar o DynamoDB Accelerator (DAX) no exemplo anterior, use também as unidades de capacidade de leitura (RCUs) em cada item na chamada TransactWriteItems. Então, você precisa provisionar seis RCUs adicionais na tabela.

De forma semelhante, se sua aplicação executa uma transação de leitura por segundo, e cada transação lê itens de 500 bytes na sua tabela, é preciso prover seis unidades de capacidade de leitura (RCUs) na tabela. A leitura de cada item requer duas RCUs: uma para preparar a transação e uma para enviar a transação.

Além disso, comportamento de SDK padrão é tentar transações novamente em caso de uma exceção TransactionInProgressException. Planeje para as unidades de capacidade de leitura adicional (RCUs) que essas tentativas repetitivas consumem. O mesmo é verdade se você estiver tentando novamente transações em seu código usando um ClientRequestToken.

Práticas recomendadas para transações

Considere as seguintes práticas recomendadas ao usar transações do DynamoDB.

  • Habilitar Auto Scaling nas suas tabelas, ou garantir que você tem capacidade de throughput suficiente para realizar as duas operações de leitura ou gravação em cada item na transação.

  • Se não estiver usando um SDK fornecido pela AWS, inclua um atributo ClientRequestToken quando realizar uma chamada TransactWriteItems para garantir que a solicitação é idempotente.

  • Não agrupe operações em uma transação se não for necessário. Por exemplo, se uma transação única com 10 operações puder ser separada em várias transações sem comprometimento da exatidão do aplicativo, recomendamos separar a transação. Transações mais simples melhorar a taxa de transferência e têm maior chance de êxito.

  • Transações múltiplas atualizando os mesmos itens simultaneamente podem causar conflitos que cancelam as transações. Recomendamos as práticas recomendadas do DynamoDB a seguir para modelagem de dados a fim de minimizar esses conflitos.

  • Se um conjunto de atributos for frequentemente atualizado entre vários itens como parte de uma única transação, considere agrupar os atributos em um único item para reduzir o escopo da transação.

  • Evite usar transações para adicionar dados no grupo. Para gravações em grupo, é melhor usar BatchWriteItem.

Usar APIs Transacionais com tabelas globais

As operações contidas em uma transação do DynamoDB só são garantidas como transacionais na região em que a transação foi originalmente executada. A transacionalidade não é preservada quando as alterações aplicadas em uma transação são replicadas entre regiões em réplicas de tabelas globais.

Transações do DynamoDB comparadas com biblioteca de clientes de transações do AWSLabs

As transações do DynamoDB fornecem uma substituição mais eficiente em termos de custos, efetiva e com maior performance para as transações da biblioteca de clientes do AWSLabs. Sugerimos atualizar os aplicativos para usar com as APIs de transação do lado do servidor nativas.