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
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
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 rodadoSe 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
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.