0Pricing
SQL Academy · Aula

Interbloqueios: detecção e prevenção

Entenda como os interbloqueios ocorrem, como o PostgreSQL os detecta e projete regras de ordenação de bloqueios que os impeçam.

Interbloqueios: detecção e prevenção é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.

O que é um impasse?

Duas transações mantêm, cada uma, um bloqueio que a outra deseja — nenhuma pode prosseguir. O banco de dados detecta o ciclo e aborta uma das transações.

Um impasse clássico

A transação A bloqueia a linha 1, e a transação B bloqueia a linha 2. A pede a linha 2, e B pede a linha 1. O sistema fica travado.

-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...

-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...

-- ERROR: deadlock detected

O PostgreSQL detecta impasses

A cada deadlock_timeout (1 segundo por padrão), o PostgreSQL verifica se há ciclos de bloqueios. Se encontrar um, aborta uma transação com o código de erro 40P01.

ERROR:  deadlock detected
DETAIL:  Process 1234 waits for ShareLock on transaction 5678 ...

Regra da ordem dos bloqueios

A solução: adquira sempre os bloqueios na mesma ordem em todos os caminhos do código.

-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);

Impasses em linhas muito disputadas

Atualizações rápidas nas mesmas linhas muito disputadas costumam causar esperas por bloqueios, não impasses. Use enfileiramento, particione a linha disputada ou serialize as atualizações no código da aplicação.

FOR UPDATE bloqueia linhas lidas

Adquira bloqueios de gravação no momento da leitura para evitar surpresas mais tarde:

BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Ignorando linhas bloqueadas

Para tabelas de filas, use o padrão "obter qualquer linha disponível":

SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have locked

NOWAIT

Falhe imediatamente em vez de esperar:

SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"

Diagnosticando impasses

Aumente log_lock_waits e capture o contexto do impasse no registro. A entrada do registro mostra as duas transações e suas consultas.

Ciclo de repetição na aplicação

Os impasses podem ser recuperados — tente novamente a transação abortada:

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    await runTransaction();
    break;
  } catch (e) {
    if (e.code === '40P01') continue;     // deadlock
    throw e;
  }
}

Reduzindo o alcance dos bloqueios

Encurte as transações — cada linha acessada permanece bloqueada até COMMIT. Não faça chamadas HTTP nem cálculos demorados dentro de uma transação.

Indexe chaves estrangeiras para evitar a escalada de bloqueios

Ao excluir um elemento pai, cada linha filha é verificada. Sem um índice de FK, isso resulta em uma varredura completa da tabela AND bloqueios de linha. Indexe cada coluna de FK.

Recapitulação

Impasses acontecem — projete o sistema para minimizá-los.

  • Adquira os bloqueios em uma ordem consistente
  • Use FOR UPDATE antecipadamente para declarar a intenção
  • Use SKIP LOCKED para filas
  • Tente novamente em caso de erros de impasse (40P01)
  • Mantenha as transações curtas

Verificação rápida

Qual é o princípio de design mais confiável para evitar impasses?

Perguntas Frequentes

A aula “Interbloqueios: detecção e prevenção” é grátis?

Sim — o texto completo de “Interbloqueios: detecção e prevenção” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.

O que vou aprender em “Interbloqueios: detecção e prevenção”?

Entenda como os interbloqueios ocorrem, como o PostgreSQL os detecta e projete regras de ordenação de bloqueios que os impeçam. Você pratica SQL Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Academy?

Nenhuma experiência prévia é necessária. SQL Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Interbloqueios: detecção e prevenção”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Academy?

Sim. Cada aula de SQL Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Propriedades ACID e anomalias
  2. Níveis de isolamento: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  3. Interbloqueios: detecção e prevenção
  4. Bloqueio otimista vs pessimista
← Voltar para SQL Academy