Descrever os níveis de isolamento

Concluído

O PostgreSQL tem três níveis de isolamento de transações que evitam três tipos de conflitos de simultaneidade, 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, esta atualização nunca é confirmada.

Por exemplo, uma transação ocorre em uma conta poupança que levaria o saldo da conta a menos de zero. Antes da transação ser confirmada, o saldo da conta é verificado e a transação é revertida, uma vez que as contas poupança não podem ter um saldo inferior a zero. Ao mesmo tempo, está a ser elaborado um relatório para mostrar o saldo corrente de todas as contas poupança. Se leituras sujas forem permitidas, o saldo negativo será devolvido, mesmo que nunca se comprometa.

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 são um custo de 10 e o número de unidades de 3. A conexão B inicia outra transação e atualiza a mesma ordem para definir o custo por unidade para 12. Na mesma transação que a consulta original, a Conexão A calcula o custo total da ordem. Se leituras não repetíveis forem permitidas, a Conexão A devolve o custo por unidade de 10, o número de unidades de 3 e o custo total de 36, o que obviamente não faz sentido.

Fantasma lê

Uma leitura fantasma ocorre se 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. A Conexão B então 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 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 executou a consulta de contagem de faturas. Esse cálculo agora retorna uma média incorreta de 100, embora a nova loja tivesse 200 faturas que a transação Conexão A não contabilizava em seu cálculo médio.

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 os conflitos de simultaneidade:

Nível de isolamento Leitura suja Leitura não repetível Leitura fantasma
Ler sem compromisso* Possível Possível Possível
Leia comprometido Não é possível Possível Possível
Leitura repetível Não é possível Não é possível Possível
Serializável Não é possível Não é possível Não é possível

* Não disponível em PostgreSQL

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, pois evita leituras sujas enquanto proporciona 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 dentro de uma transação veriam 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 mais alto nível de isolamento de transação e funciona como se diferentes transações estivessem sendo executadas 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 tem que 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 quaisquer linhas que outras transações modifiquem durante a transação serializável. Se essa forma de conflito ocorrer, uma mensagem de erro será retornada e, portanto, é importante ter a lógica de repetição incorporada aos aplicativos quando as transações serializáveis forem usadas.

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

Por exemplo:

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