Descrever níveis de isolamento

Concluído

PostgreSQL tem três níveis de isolamento de transação que previnem três tipos de conflitos de concorrência: leituras sujas, leituras não repetíveis e leituras fantasmas.

Tipos de conflito de simultaneidade

Leituras sujas

Uma leitura suja ocorre quando uma transação lê a versão atualizada dos dados que outra transação está editando. No entanto, essa atualização nunca é confirmada.

Por exemplo, ocorre uma transação em uma conta poupança que levaria o saldo da conta abaixo de zero. Antes de a transação ser confirmada, o saldo da conta é verificado e a transação é revertida, pois as contas de poupança não podem ter um saldo abaixo de zero. Ao mesmo tempo, um relatório está sendo executado para mostrar o saldo atual de todas as contas-poupança. Se leituras sujas forem permitidas, o saldo negativo será retornado, mesmo que nunca seja confirmado.

Leituras não repetíveis

Uma leitura não repetível ocorre se uma transação: lê dados, outra transação atualiza os dados e a transação inicial lê os dados novamente e vê as novas atualizações.

Por exemplo, a Conexão A inicia uma transação e lê o custo por unidade e o número de unidades de um pedido, que é um custo de 10 e um número de unidades de 3. Em seguida, a Conexão B inicia outra transação e atualiza o mesmo pedido para definir o custo por unidade como 12. Na mesma transação que a consulta original, a Conexão A calcula o custo total do pedido. Se leituras não repetíveis forem permitidas, a Conexão A retornará um custo por unidade de 10, um número de unidades de 3 e um custo total de 36, o que obviamente não faz sentido.

Leituras fantasma

Uma leitura fantasma ocorre quando uma transação: lê dados, outra transação adiciona uma nova linha (ou linhas) aos dados e a transação inicial lê os dados novamente e vê as novas atualizações.

Por exemplo, a Conexão A inicia uma transação e conta o número total de faturas do dia em Paris. A contagem totalizou 1.100 faturas para todas as 10 lojas em Paris. Em seguida, a Conexão B inicia outra transação e adiciona uma nova loja de varejo em Paris com 200 faturas para o dia de abertura da nova loja. Na transação da Conexão A, o sistema agora conta o número de lojas para calcular o número de faturas por loja. A conexão A agora dividiria as 1.100 transações por 11 lojas em vez das 10 originais que existiam quando ela executava a consulta de contagem de faturas. Esse cálculo agora retorna uma média incorreta de 100, embora a nova loja tenha 200 faturas que a transação da Conexão A não considerou em seu cálculo de média.

Níveis de isolamento

O Banco de Dados do Azure para PostgreSQL tem três níveis de isolamento de transação, leitura confirmada, leitura repetível e serializável. A leitura não confirmada não está disponível no Banco de Dados do Azure para PostgreSQL.

Como os níveis de isolamento afetam conflitos de simultaneidade:

Nível de isolamento Leitura suja Leitura não repetível Leitura-fantasma
Leitura não confirmada* Possível Possível Possível
Leitura confirmada Impossível Possível Possível
Leitura repetida Impossível Impossível Possível
Serializável Impossível Impossível Impossível

* Não disponível no PostgreSQL

A leitura confirmada é o nível de isolamento padrão no Banco de Dados do Azure para PostgreSQL. A leitura confirmada é mais apropriada para a maioria dos cenários porque impede leituras sujas, fornecendo um bom desempenho. É possível ter leituras não repetíveis e leituras fantasmas, mas essas condições só podem ocorrer se houver várias instruções SELECT consultando simultaneamente os mesmos dados.

A leitura repetível difere da leitura confirmada porque várias instruções SELECT em uma transação apresentariam os mesmos resultados, mesmo que outra transação atualizasse as linhas entre a execução das duas instruções SELECT da transação. Se outra transação inserir novas linhas, essas linhas não aparecerão nos resultados da segunda instrução SELECT.

O nível de isolamento serializável fornece o nível mais alto de isolamento da transação e executa como se diferentes transações estivessem em execução em série, ou seja, uma após a outra. A desvantagem do nível de isolamento serializável é que, se uma transação estiver executando uma atualização, outras transações poderão bloqueá-la. A transação serializável precisa esperar até que a transação de bloqueio seja concluída, o que afeta o desempenho.

As transações serializáveis também não podem fazer alterações em nenhuma linha que outras transações modifiquem durante a transação serializável. Se essa forma de conflito ocorrer, uma mensagem de erro será retornada, portanto, é importante ter a lógica de repetição incorporada em aplicativos quando transações serializáveis são usadas.

Para atualizar os níveis de isolamento da transação, use o comando TRANSACTION ISOLATION LEVEL em uma transação.

Por exemplo:

BEGIN TRANSACTION
TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM humanresources.department
COMMIT;