Descrever níveis de isolamento
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;