Serialização e isolamento de transações

Esta página descreve a contenção, a serialização e o isolamento de dados transacionais. Para exemplos de código de transação, consulte transações e gravações em lote.

Transações e contenção de dados

Para que uma transação seja bem-sucedida, os documentos recuperados pelas suas operações de leitura devem permanecer inalterados por operações fora da transação. Se outra operação tentar alterar um desses documentos, essa operação entrará em um estado de contenção de dados com a transação.

Contenção de dados
Quando duas ou mais operações competem pelo controle do mesmo documento. Por exemplo, uma transação pode exigir que um documento permaneça consistente enquanto uma operação simultânea tenta atualizar os valores dos campos desse documento.

O Cloud Firestore resolve a contenção de dados atrasando ou falhando uma das operações. As bibliotecas cliente do Cloud Firestore repetem automaticamente as transações que falham devido à contenção de dados. Após um número finito de novas tentativas, a operação de transação falha e retorna uma mensagem de erro:

ABORTED: Too much contention on these documents. Please try again.

Ao decidir qual operação falhará ou atrasará, o comportamento dependerá do tipo de biblioteca cliente.

  • Os SDKs móveis/web usam controles de simultaneidade otimistas.

  • As bibliotecas cliente do servidor usam controles de simultaneidade pessimistas.

Contenção de dados nos SDKs móveis/web

Os SDKs móveis/web (plataformas Apple, Android, Web, C++) usam controles de simultaneidade otimistas para resolver a contenção de dados.

Controles de simultaneidade otimistas
Com base na suposição de que a contenção de dados não é provável ou que não é eficiente manter bloqueios de banco de dados. As transações otimistas não usam bloqueios de banco de dados para impedir que outras operações alterem os dados.

Os SDKs móveis/web usam controles de simultaneidade otimistas, porque podem operar em ambientes com alta latência e uma conexão de rede não confiável. Bloquear documentos em um ambiente de alta latência causaria muitas falhas na contenção de dados.

Nos SDKs móveis/web, uma transação rastreia todos os documentos que você lê dentro da transação. A transação completa suas operações de gravação somente se nenhum desses documentos for alterado durante a execução da transação. Se algum documento for alterado, o manipulador de transação tentará novamente a transação. Se a transação não conseguir obter um resultado limpo após algumas tentativas, a transação falhará devido à contenção de dados.

Contenção de dados nas bibliotecas cliente do servidor

As bibliotecas cliente do servidor (C#, Go, Java, Node.js, PHP, Python, Ruby) usam controles de simultaneidade pessimistas para resolver a contenção de dados.

Controles de simultaneidade pessimistas
Com base na suposição de que a contenção de dados é provável. As transações pessimistas usam bloqueios de banco de dados para evitar que outras operações modifiquem os dados.

As bibliotecas cliente do servidor usam controles de simultaneidade pessimistas, porque pressupõem baixa latência e uma conexão confiável com o banco de dados.

Nas bibliotecas cliente do servidor, as transações bloqueiam os documentos que lêem. O bloqueio de uma transação em um documento impede que outras transações, gravações em lote e gravações não transacionais alterem esse documento. Uma transação libera seus bloqueios de documentos no momento da confirmação. Ele também libera seus bloqueios se atingir o tempo limite ou falhar por qualquer motivo.

Quando uma transação bloqueia um documento, outras operações de gravação devem esperar que a transação libere seu bloqueio. As transações adquirem seus bloqueios em ordem cronológica.

Isolamento serializável

A contenção de dados entre transações está intimamente relacionada aos níveis de isolamento do banco de dados. O nível de isolamento de um banco de dados descreve quão bem o sistema lida com conflitos entre operações simultâneas. O conflito vem dos seguintes requisitos de banco de dados:

  • As transações exigem dados precisos e consistentes.
  • Para usar os recursos com eficiência, os bancos de dados executam operações simultaneamente.

Em sistemas com baixo nível de isolamento, uma operação de leitura dentro de uma transação pode ler dados imprecisos de alterações não confirmadas em uma operação simultânea.

O isolamento serializável define o nível de isolamento mais alto. Isolamento serializável significa que:

  • Você pode assumir que o banco de dados executa transações em série.
  • As transações não são afetadas por alterações não confirmadas em operações simultâneas.

Esta garantia deve ser mantida mesmo quando o banco de dados executa múltiplas transações em paralelo. O banco de dados deve implementar controles de simultaneidade para resolver conflitos que quebrariam esta garantia.

O Cloud Firestore garante isolamento serializável de transações. As transações no Cloud Firestore são serializadas e isoladas por tempo de confirmação.

Isolamento serializável por tempo de confirmação

O Cloud Firestore atribui a cada transação um tempo de confirmação que representa um único momento. Quando o Cloud Firestore confirma as alterações de uma transação no banco de dados, você pode presumir que todas as leituras e gravações na transação ocorrem exatamente no momento do commit.

A execução real de uma transação requer algum tempo. A execução de uma transação começa antes do tempo de confirmação e a execução de múltiplas operações pode se sobrepor. O Cloud Firestore mantém isolamento serializável e garante que:

  • O Cloud Firestore confirma as transações em ordem de tempo de confirmação.
  • O Cloud Firestore isola transações de operações simultâneas com um tempo de confirmação posterior.

No caso de contenção de dados entre operações simultâneas, o Cloud Firestore usa controles de simultaneidade otimistas e pessimistas para resolver a contenção.

Isolamento dentro de uma transação

O isolamento de transação também se aplica a operações de gravação dentro de uma transação. Consultas e leituras dentro de uma transação não veem os resultados de gravações anteriores dentro dessa transação. Mesmo se você modificar ou excluir um documento em uma transação, todas as leituras de documentos nessa transação retornarão a versão do documento no momento da confirmação, antes das operações de gravação da transação. As operações de leitura não retornam nada se o documento ainda não existia.

Problemas com contenção de dados

Para obter mais informações sobre contenção de dados e como resolvê-los, consulte a página de solução de problemas .