CodeGym /Cursos /SQL SELF /Nível de isolamento READ COMMITTED

Nível de isolamento READ COMMITTED

SQL SELF
Nível 40 , Lição 0
Disponível

Bora entender o que faz o nível de isolamento READ COMMITTED. O nome já dá a dica: tudo que a gente lê dentro da transação já foi "committed" por outras transações. Tipo na vida real, quando só acreditamos nas fofocas que já estão registradas oficialmente.

Falando sério, esse nível garante que uma transação não consegue ver mudanças feitas por outras transações que ainda não foram confirmadas. Isso resolve o problema conhecido como "leitura suja" (Dirty Read). Mas fica ligado: os dados que você lê podem mudar se outra transação der commit entre os seus selects. Isso gera o risco da tal "leitura não-repetível" (Non-Repeatable Read).

No PostgreSQL, o nível de isolamento READ COMMITTED já vem como padrão. É tipo o modo default — não precisa configurar nada pra usar.

Exemplo de uso do nível de isolamento READ COMMITTED

Bora ver como isso funciona na prática. Imagina que temos uma tabela accounts com informações dos usuários e seus saldos:

CREATE TABLE accounts (
    account_id SERIAL PRIMARY KEY,
    account_name TEXT NOT NULL,
    balance NUMERIC(10, 2) NOT NULL
);

INSERT INTO accounts (account_name, balance)
VALUES ('Alice', 1000.00), ('Bob', 500.00);

Agora imagina a seguinte situação. Sessão 1 e Sessão 2 — nossos dois personagens, ambos mexendo na tabela accounts. Olha só o que rola:

Sessão 1:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';
-- Nenhum COMMIT ou ROLLBACK por enquanto.

Nesse momento, 100 unidades foram temporariamente tiradas do balance da Alice, mas ainda não foi confirmado.

Sessão 2:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

BEGIN;
SELECT balance FROM accounts WHERE account_name = 'Alice';

Resultado: a Sessão 2 vê o saldo da Alice como 1000.00, porque a transação da Sessão 1 ainda não terminou (COMMIT não rolou). O nível READ COMMITTED protege a gente da "leitura suja".

Sessão 1 finaliza a transação:

COMMIT;

Agora o saldo da Alice foi atualizado e o valor 900.00 ficou registrado no banco.

Sessão 2 repete o select:

SELECT balance FROM accounts WHERE account_name = 'Alice';

Resultado: agora a Sessão 2 vê o saldo atualizado da Alice — 900.00. Repara que o resultado mudou em relação ao select anterior, que retornava 1000.00. Isso é o problema da "leitura não-repetível".

Quando usar READ COMMITTED?

O nível de isolamento READ COMMITTED é aquele equilíbrio entre performance e consistência. Mas tem uns cenários em que ele cai como uma luva:

  1. Operações CRUD simples: quando você só lê ou atualiza dados sem muita relação complicada.

  2. Atualização de registros: tipo atualizar vários dados de uma vez na tabela, onde é importante ver logo as mudanças confirmadas.

  3. Processamento de transações: sistemas de pagamento onde o usuário só pode ver dados já confirmados.

Mas se você faz consultas analíticas pesadas ou mexe com grandes volumes de dados, talvez seja melhor pensar em outro nível de isolamento, tipo REPEATABLE READ.

Vantagens e desvantagens do nível de isolamento READ COMMITTED

O nível de isolamento READ COMMITTED é tipo o meio-termo. Ele te protege de dados sujos: você não vê mudanças que outra transação começou mas ainda não terminou. Ou seja, ninguém lê informação "crua" que pode ser revertida logo depois.

Esse modo é mais rápido que níveis mais rígidos (REPEATABLE READ ou SERIALIZABLE), porque não precisa de locks complicados nem checagens extras. Ele é leve e, ao mesmo tempo, confiável — por isso é o padrão e serve bem pra maioria das tarefas do dia a dia.

Apesar de evitar leitura suja, o READ COMMITTED não protege contra:

  • "Leitura não-repetível" (Non-Repeatable Read): o valor dos dados pode mudar se outra transação fizer alterações entre seus selects.
  • "Leitura fantasma" (Phantom Read): outra transação pode adicionar linhas que mudam o resultado da sua consulta.

Dicas pra trabalhar com READ COMMITTED

Sempre finalize suas transações: não esquece de usar COMMIT ou ROLLBACK, senão pode dar ruim com locks presos.

Veja se o nível de isolamento é suficiente: se você precisa garantir que os dados não mudem durante a transação, pensa em usar REPEATABLE READ.

Use indexação: isso ajuda o PostgreSQL a achar os dados mais rápido e aplicar as mudanças de boa.

Exemplo: processamento de pedidos

Imagina que temos uma tabela orders onde ficam os dados dos pedidos:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_name TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending'
);

INSERT INTO orders (customer_name, status)
VALUES ('Alice', 'pending'), ('Bob', 'pending');

A gente quer atualizar o status dos pedidos que estão como "pending":

BEGIN;
SELECT * FROM orders WHERE status = 'pending';
UPDATE orders SET status = 'completed' WHERE status = 'pending';
COMMIT;

Se durante esse processo outra transação adicionar um novo pedido com status "pending" e der COMMIT, a nossa transação não vai considerar essa linha, porque ela foi inserida depois do início da leitura.

Esse é o exemplo de "leitura fantasma". Se quiser evitar esse tipo de situação, tem que usar SERIALIZABLE.

O nível de isolamento READ COMMITTED é o padrão na maioria dos bancos de dados, incluindo o PostgreSQL. Ele protege contra leituras sujas, o que já faz dele uma boa escolha pra maioria das operações normais. Mas em cenários que exigem consistência mais rígida, talvez você precise de níveis de isolamento mais fortes. A escolha do nível de isolamento depende das suas necessidades e dos requisitos de performance do seu sistema.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION