Aprenda / SQL e banco de dados

IntermediárioAula 11 de 1615 min0% da trilha

Transações e ACID

Dois UPDATE que precisam acontecer juntos ou nenhum dos dois — o problema que uma transação existe pra resolver.

Transferir dinheiro entre duas contas parece só dois UPDATE: debitar de uma, creditar na outra. Mas se o segundo UPDATE falhar — queda de conexão, erro de aplicação, o que for — depois do primeiro já ter rodado, o dinheiro simplesmente desaparece: saiu de uma conta e nunca chegou na outra. É exatamente esse problema que uma transação resolve.

BEGIN, COMMIT — agrupando comandos que precisam ser tudo ou nada

SQL
BEGIN;

UPDATE contas SET saldo = saldo - 200 WHERE id = 1;
UPDATE contas SET saldo = saldo + 200 WHERE id = 2;

COMMIT;

Entre BEGIN e COMMIT, os dois UPDATE fazem parte da mesma transação. Só quando o COMMIT roda é que as mudanças ficam gravadas de verdade — até lá, elas existem só dentro da transação em andamento.

ROLLBACK — desfazer tudo, como se nada tivesse acontecido

SQL
BEGIN;

UPDATE contas SET saldo = saldo - 200 WHERE id = 1;
-- algo deu errado aqui (ex.: o saldo ficaria negativo)

ROLLBACK;
-- nenhuma das linhas mudou — é como se a transação inteira nunca tivesse rodado

Se qualquer comando dentro da transação falhar, ou se você decidir explicitamente que não quer aplicar as mudanças, ROLLBACK desfaz tudo que aconteceu desde o BEGIN. É essa garantia de "tudo ou nada" que resolve o problema da transferência: se o crédito na segunda conta falhar, um ROLLBACK desfaz o débito da primeira também.

ACID — o que cada letra garante na prática

referência rápida
Atomicity (Atomicidade)
  Todos os comandos da transação acontecem, ou nenhum acontece.
  → a transferência não pode debitar sem creditar.

Consistency (Consistência)
  A transação nunca deixa o banco num estado que viola suas regras
  (CHECK, FOREIGN KEY, UNIQUE...), mesmo que precise abortar no meio.
  → um saldo não pode ficar negativo se existe CHECK (saldo >= 0).

Isolation (Isolamento)
  Transações rodando ao mesmo tempo não enxergam o estado parcial
  (não commitado) uma da outra.
  → outra consulta não vê o saldo "só debitado, ainda não creditado".

Durability (Durabilidade)
  Depois do COMMIT, a mudança persiste mesmo que o banco trave ou
  a energia caia logo em seguida.
  → a transferência não "desaparece" se o servidor reiniciar.

Repare que Consistency depende das constraints que você já viu nas lições 7 e 12 — uma transação não inventa regra nenhuma, ela só garante que as regras existentes nunca fiquem violadas nem temporariamente.

O banco aborta a transação inteira se um comando falhar

Em Postgres, se um comando dentro de BEGIN...COMMIT falha (por exemplo, viola uma CHECK), a transação inteira entra num estado de erro — nenhum comando seguinte roda até você digitar ROLLBACK. Não existe "só desfazer o comando que falhou e seguir com o resto": é tudo ou nada, do BEGIN até o fim.

Exercício

Escreva a transação que transfere R$ 100 da conta de id 3 pra conta de id 4, e explique numa frase por que os dois UPDATE precisam estar dentro do mesmo BEGIN/COMMIT.

Quiz rápido

Por que a transferência bancária (debitar de uma conta, creditar em outra) precisa ser uma transação atômica?
O que a garantia de Durability (o D de ACID) assegura?