Transações em Banco de Dados: entenda ACID, commit e rollback
Entenda como transações em banco de dados aplicam ACID, commit, rollback, savepoints e isolamento para manter operações consistentes e seguras.

Uma transferência bancária não pode debitar uma conta e, por causa de uma falha, esquecer de creditar a outra.
Para impedir esse tipo de estado incompleto, os bancos de dados agrupam operações relacionadas em uma unidade lógica: a transação.
Transações em banco de dados garantem que um conjunto de comandos seja confirmado por inteiro ou desfeito quando algo dá errado.
Essa proteção é resumida pelas propriedades ACID e controlada por recursos como BEGIN, COMMIT, ROLLBACK, savepoints e níveis de isolamento.
Neste guia, você entenderá esses conceitos com um exemplo prático, verá como a concorrência afeta os dados e aprenderá a definir transações curtas, seguras e adequadas à regra de negócio.
O que é uma transação em banco de dados?
Uma transação é uma sequência de leituras e alterações tratada pelo banco como uma única operação lógica.
Enquanto ela está em andamento, comandos podem modificar várias linhas e tabelas. Ao final, o sistema confirma o conjunto ou restaura o estado anterior.
O limite correto não depende da quantidade de comandos, mas da regra de negócio.
Criar um pedido, reservar estoque e registrar o pagamento local podem formar uma unidade. Se apenas uma dessas etapas for persistida, o sistema passa a representar uma realidade impossível.
Isso não significa que toda consulta precise de um bloco longo. Uma leitura simples já pode ser executada dentro de uma transação implícita.
O desenvolvedor declara uma transação explicitamente quando precisa controlar o início, o sucesso, a falha e a visibilidade de várias operações relacionadas.
Como uma transação funciona
De forma simplificada, a aplicação inicia a transação, executa os comandos, verifica as condições necessárias e então decide entre confirmar ou desfazer.
O banco mantém informações suficientes para controlar concorrência e recuperar o estado consistente em caso de erro.
- A aplicação abre a transação.
- Lê ou altera os registros necessários.
- Valida o resultado e as regras de negócio.
- Executa
COMMITse tudo estiver correto. - Executa
ROLLBACKdiante de erro ou condição inválida.
A documentação de transações do PostgreSQL descreve esse agrupamento como “tudo ou nada” e mostra que estados intermediários não devem ficar visíveis a outras transações.
A sintaxe exata varia entre produtos, mas o princípio é comum aos bancos relacionais.
Exemplo: transferência entre contas
BEGIN;
UPDATE contas SET saldo = saldo - 100 WHERE id = 1;
UPDATE contas SET saldo = saldo + 100 WHERE id = 2;
COMMIT;
Se a segunda atualização falhar, a aplicação deve executar ROLLBACK. Assim, o débito da primeira conta também é desfeito.
Na prática, ainda seriam necessárias validações como saldo disponível, existência das contas e número de linhas afetadas.
O que significa ACID?
ACID reúne quatro propriedades desejáveis de uma transação: atomicidade, consistência, isolamento e durabilidade. Elas trabalham em conjunto, mas resolvem problemas diferentes.
A definição também aparece no guia oficial de transações e controle de concorrência do SQL Server.

Atomicidade
A atomicidade determina que a unidade seja indivisível do ponto de vista do resultado: todas as alterações são aplicadas ou nenhuma permanece.
Ela não quer dizer que os comandos acontecem literalmente no mesmo instante, e sim que uma execução incompleta não será confirmada.
Consistência
A consistência exige que a transação leve o banco de um estado válido a outro. Restrições de chave, unicidade e integridade referencial ajudam, mas o banco não adivinha todas as regras do negócio.
Se “saldo nunca pode ficar negativo” for uma regra, ela precisa ser representada por validação, restrição ou desenho apropriado.
Isolamento
O isolamento controla como transações simultâneas percebem as alterações umas das outras. Sem proteção suficiente, duas requisições podem ler o mesmo estado e gravar resultados conflitantes.
Quanto maior o isolamento, menores certas anomalias, mas maior pode ser o custo em bloqueios, abortos ou tentativas repetidas.
Durabilidade
A durabilidade significa que, depois do COMMIT, a alteração deve sobreviver a falhas previstas pelo mecanismo. Bancos usam logs de transação, escrita em armazenamento e recuperação.
As garantias concretas dependem da configuração, do hardware, da replicação e das opções de confirmação adotadas.
BEGIN, COMMIT e ROLLBACK
BEGIN — ou START TRANSACTION, conforme o banco — abre um limite explícito. COMMIT confirma as alterações. ROLLBACK encerra a transação descartando o que ainda não foi confirmado.
O comando ROLLBACK documentado pela Microsoft também mostra particularidades envolvendo transações aninhadas e savepoints no SQL Server.

O ponto importante é controlar todos os caminhos de saída. Exceções, cancelamentos e retornos antecipados não podem deixar uma conexão presa com transação aberta.
Bibliotecas e frameworks oferecem blocos que confirmam no sucesso e revertem na falha, mas o comportamento deve ser conhecido e testado.
Savepoints e recuperação parcial
Um savepoint marca um ponto intermediário dentro da transação. Em vez de desfazer tudo, a aplicação pode voltar à marca e continuar.
Isso é útil quando uma etapa opcional pode falhar sem invalidar a unidade inteira.
BEGIN;
UPDATE pedidos SET status = 'pago' WHERE id = 42;
SAVEPOINT antes_do_bonus;
UPDATE cupons SET usos = usos + 1 WHERE id = 7;
ROLLBACK TO SAVEPOINT antes_do_bonus;
COMMIT;
O recurso não substitui um bom limite transacional. Uma rotina cheia de pontos de retorno pode esconder uma regra confusa.
Além disso, “transações aninhadas” têm semânticas diferentes entre bancos e frameworks; confirme o que realmente é confirmado no nível externo.
Autocommit e transações explícitas
No modo autocommit, cada comando é tratado e confirmado individualmente quando termina com sucesso.
É conveniente para operações independentes, mas não preserva atomicidade entre dois comandos. Se débito e crédito forem enviados separadamente, o primeiro poderá ser confirmado antes de o segundo falhar.
Uma transação explícita resolve esse agrupamento, desde que todos os comandos usem a mesma conexão e o mesmo contexto transacional.
Em aplicações com pools de conexão, esse detalhe é decisivo: abrir a transação em uma conexão e executar parte do trabalho em outra rompe a unidade esperada.
Concorrência e anomalias
Transações não servem apenas para lidar com erros. Elas também coordenam usuários e processos que acessam os mesmos dados ao mesmo tempo.
Esse problema aparece em estoque, reserva de assentos, limites financeiros e qualquer recurso disputado.
- Leitura suja: uma transação lê uma alteração ainda não confirmada.
- Leitura não repetível: a mesma linha retorna valores diferentes durante a transação.
- Leitura fantasma: uma consulta repetida encontra linhas novas ou removidas.
- Atualização perdida: uma gravação sobrescreve o resultado concorrente sem percebê-lo.
O comportamento exato varia conforme o banco e a implementação do isolamento. Para evitar atualizações perdidas, podem ser usados bloqueios, comparação de versão, operações atômicas ou isolamento mais forte.
Em APIs que recebem requisições repetidas, a idempotência complementa a transação ao impedir que o mesmo efeito de negócio seja aplicado duas vezes.
Níveis de isolamento
O padrão SQL define níveis que equilibram consistência e concorrência. A documentação de isolamento do PostgreSQL explica os fenômenos permitidos e as diferenças da implementação.
Não presuma que dois bancos com o mesmo nome de nível se comportem de forma idêntica em todos os casos.
| Nível | Ideia geral | Uso típico |
|---|---|---|
| Read Uncommitted | Proteção mínima; pode permitir leituras sujas em alguns bancos | Raro quando precisão importa |
| Read Committed | Cada comando lê dados já confirmados | Padrão comum para aplicações |
| Repeatable Read | Busca manter leituras estáveis durante a transação | Fluxos que dependem do mesmo retrato |
| Serializable | Resultado equivalente a uma execução serial válida | Regras críticas, aceitando abortos e novas tentativas |
O nível mais alto não deve ser escolhido automaticamente. Serializable pode exigir que a aplicação repita transações abortadas.
Um nível mais fraco pode ser suficiente quando há restrições, comandos atômicos e controle otimista bem desenhados.
Locks, MVCC e deadlocks
Locks restringem acessos conflitantes a linhas, páginas ou outros recursos.
Já o controle de concorrência multiversão, conhecido como MVCC, mantém versões que permitem a leitores observar um retrato coerente sem bloquear toda gravação.
Muitos bancos combinam versões e bloqueios.
Um deadlock ocorre quando transações aguardam recursos retidos umas pelas outras. O banco detecta o ciclo e aborta uma participante.
A aplicação precisa tratar esse erro como recuperável quando a operação puder ser repetida com segurança, aplicando poucas tentativas e atraso controlado.
Acessar tabelas e registros em ordem consistente reduz ciclos. Transações curtas também liberam recursos mais cedo.
Consultas bem planejadas e índices adequados no banco de dados diminuem o volume examinado e podem reduzir a duração de bloqueios, embora índices não corrijam uma regra concorrente incorreta.
Quando usar transações
Use uma transação quando várias alterações locais representam uma única decisão de negócio.
Exemplos incluem criar pedido e itens, registrar pagamento e atualizar saldo, transferir estoque entre depósitos e salvar uma entidade com seu histórico obrigatório.
Também faz sentido para leituras que precisam de um retrato estável ou para a sequência “ler, validar e gravar”, desde que o isolamento escolhido realmente proteja a hipótese.
Se você está aprendendo a estruturar essas operações, o guia de PostgreSQL para iniciantes oferece uma base sobre tabelas, comandos e administração.
Quando uma transação local não basta
Uma transação do banco protege recursos controlados por aquele gerenciador.
Ela não desfaz automaticamente um e-mail já enviado, uma cobrança em provedor externo ou uma mensagem entregue a outro serviço.
Manter a transação aberta durante uma chamada de rede prolonga locks e ainda não transforma dois sistemas em uma unidade atômica.
Em arquiteturas distribuídas, o Transactional Outbox grava a mudança de negócio e o evento na mesma transação local, para posterior publicação confiável.
Quando um processo atravessa vários serviços, o padrão Saga coordena etapas e compensações em vez de depender de um rollback global.
Essas abordagens não eliminam falhas duplicadas ou reordenação. Consumidores ainda precisam ser idempotentes, observar estados intermediários e registrar informação suficiente para recuperação e auditoria.
Boas práticas
- Mantenha o escopo pequeno: faça dentro da transação apenas o trabalho que precisa da mesma garantia.
- Valide resultados: confira linhas afetadas e condições de negócio antes do commit.
- Evite interação externa: não espere usuário, arquivo remoto ou API enquanto mantém recursos do banco.
- Escolha o isolamento conscientemente: associe o nível às anomalias que a regra não tolera.
- Trate falhas transitórias: deadlocks e conflitos serializáveis podem exigir repetição segura.
- Defina timeout: impeça que operações presas retenham conexões e locks indefinidamente.
- Observe em produção: monitore duração, espera por locks, abortos, deadlocks e uso do pool.
Teste concorrência, não apenas o caminho feliz sequencial. Duas execuções simultâneas revelam problemas que um teste isolado não encontra.
Para preparar e inspecionar cenários reais, vale dominar também as consultas SQL na prática.
Erros comuns
O primeiro erro é abrir uma transação cedo demais e confirmar tarde demais. Processamento pesado e chamadas externas ampliam a janela de contenção.
Prepare dados antes, abra a transação no momento necessário e finalize-a assim que a parte atômica terminar.
Outro erro é acreditar que ACID valida automaticamente toda regra de negócio. Uma transação pode confirmar comandos logicamente errados com perfeita atomicidade.
Restrições, modelagem, autorização e validações continuam necessárias.
Também é perigoso capturar uma exceção e continuar usando a transação sem entender seu estado. Alguns bancos marcam a transação como abortada após certos erros.
A resposta segura costuma ser reverter, liberar a conexão e reiniciar a unidade completa quando a repetição for válida.
Perguntas frequentes
Um COMMIT pode ser desfeito com ROLLBACK?
Não pela mesma transação. Depois do commit, é preciso executar uma nova operação compensatória, restaurar dados por mecanismos administrativos ou usar recursos específicos do banco.
ROLLBACK desfaz tudo no sistema?
Não. Ele desfaz alterações abrangidas pela transação e suportadas pelo mecanismo. E-mails, requisições externas e outros efeitos fora do banco não são revertidos automaticamente.
Transação é a mesma coisa que stored procedure?
Não. Uma stored procedure agrupa código executado no banco; uma transação define a unidade de confirmação e reversão. Uma procedure pode abrir ou participar de uma transação.
Qual nível de isolamento devo usar?
Use o nível mais simples que preserve as invariantes do seu caso. Comece entendendo o padrão do banco, identifique anomalias intoleráveis e teste contenção e repetição antes de elevar o isolamento.
Um SELECT precisa de transação?
Todo comando é executado sob algum controle transacional, ainda que implícito. Uma transação explícita é necessária quando várias leituras precisam compartilhar garantias específicas ou se relacionam a uma gravação.
Transações afetam o desempenho?
Sim, porque logs, versões, locks e coordenação têm custo. Ainda assim, remover transações não é uma otimização segura quando elas protegem integridade. O objetivo é reduzir duração e contenção.
Bancos NoSQL têm transações?
Alguns oferecem transações com diferentes escopos e garantias; outros privilegiam operações atômicas por documento ou chave. Consulte a documentação do produto e não transfira pressupostos de um banco relacional sem validação.
Conclusão
Transações em banco de dados transformam várias operações em uma decisão confiável.
Atomicidade evita resultados pela metade; consistência preserva invariantes representadas; isolamento controla interferências concorrentes; e durabilidade protege o que foi confirmado.
A qualidade, porém, depende do desenho: limite de negócio correto, transação curta, isolamento adequado, tratamento de conflitos e nenhuma expectativa de que o rollback alcance sistemas externos.
Ao combinar esses cuidados com restrições e observabilidade, você reduz estados impossíveis sem sacrificar a operação do sistema.