ACID vs. BASE: entendendo as propriedades das transações

1. Introdução aos modelos de transações em bancos de dados

Uma transação em banco de dados é uma unidade lógica de trabalho que agrupa uma ou mais operações (leitura, escrita, atualização ou exclusão) em uma única execução atômica. A importância das transações reside na garantia de que os dados permanecem consistentes mesmo em cenários de concorrência, falhas de hardware ou interrupções de rede.

Historicamente, os bancos de dados relacionais (como PostgreSQL, MySQL e Oracle) adotaram o modelo ACID, que prioriza consistência forte e integridade dos dados. Com o advento dos sistemas distribuídos modernos e da web em escala, surgiu o modelo BASE, adotado por bancos NoSQL (como Cassandra, DynamoDB e MongoDB), que prioriza disponibilidade e escalabilidade em detrimento da consistência imediata.

O trade-off fundamental entre ACID e BASE reflete o Teorema CAP: em sistemas distribuídos, é possível garantir no máximo duas das três propriedades — Consistência, Disponibilidade e Tolerância a Partições. ACID foca em consistência forte, enquanto BASE prioriza disponibilidade e tolerância a partições.

2. ACID: Atomicidade, Consistência, Isolamento e Durabilidade

O acrônimo ACID descreve quatro propriedades essenciais para transações confiáveis:

Atomicidade: Garante que uma transação é executada completamente ou não é executada. Se qualquer operação dentro da transação falhar, todo o conjunto é desfeito (rollback).

Exemplo de atomicidade em PostgreSQL:
BEGIN;
UPDATE contas SET saldo = saldo - 100 WHERE id = 1;
UPDATE contas SET saldo = saldo + 100 WHERE id = 2;
-- Se a segunda atualização falhar, a primeira é desfeita automaticamente
COMMIT;

Consistência: Assegura que uma transação leva o banco de dados de um estado válido para outro estado válido, respeitando todas as regras de integridade (constraints, triggers, chaves estrangeiras).

Exemplo de consistência (constraint CHECK):
CREATE TABLE contas (
    id INT PRIMARY KEY,
    saldo DECIMAL(10,2) CHECK (saldo >= 0)
);
-- Qualquer transação que tente deixar saldo negativo será rejeitada

Isolamento: Controla como transações concorrentes interagem entre si. Os níveis de isolamento padrão (do mais fraco ao mais forte) são: Read Uncommitted, Read Committed, Repeatable Read e Serializable.

Níveis de isolamento no PostgreSQL:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- Evita leitura suja, mas permite leitura não repetível

Durabilidade: Garante que, uma vez confirmada (COMMIT), a transação persiste mesmo em caso de falhas do sistema, utilizando técnicas como write-ahead logging (WAL).

Mecanismo WAL no PostgreSQL:
-- O log de transações é escrito antes dos dados reais
-- Em caso de crash, o banco recupera o estado consistente usando o WAL

3. BASE: Basically Available, Soft state, Eventual consistency

O modelo BASE foi proposto por Eric Brewer como uma alternativa ao ACID para sistemas distribuídos:

Basically Available: O sistema responde a todas as requisições, mesmo que algumas partes estejam com falhas. Não há recusa de serviço por indisponibilidade parcial.

Soft state: O estado do sistema pode mudar ao longo do tempo sem intervenção externa, devido à propagação assíncrona de atualizações entre nós.

Eventual consistency: A consistência não é garantida imediatamente, mas o sistema converge para um estado consistente em algum momento futuro, desde que não haja novas atualizações.

Exemplo de consistência eventual no Cassandra:
-- Escrita em um nó:
INSERT INTO usuarios (id, nome, email) VALUES (1, 'João', 'joao@email.com');
-- Leitura imediata de outro nó pode não refletir a alteração
-- Após propagação (segundos/minutos), todos os nós convergem

4. Comparação direta: ACID vs. BASE em cenários reais

Característica ACID BASE
Consistência Imediata e forte Eventual
Disponibilidade Pode ser sacrificada Priorizada
Tolerância a partições Limitada Alta
Latência de escrita Maior (sincronização) Menor (assíncrona)
Complexidade Menor (monolítico) Maior (distribuído)

Consistência imediata vs. consistência eventual: Em um e-commerce, o estoque precisa ser consistente imediatamente para evitar vender o mesmo item duas vezes (ACID). Já em uma rede social, uma curtida pode demorar alguns segundos para aparecer em todos os feeds (BASE).

Disponibilidade vs. integridade: Sistemas financeiros preferem indisponibilidade temporária a dados inconsistentes. Redes sociais e sistemas de recomendação toleram inconsistências temporárias em nome da disponibilidade contínua.

5. Quando escolher ACID: casos de uso clássicos

Sistemas financeiros: Transferências bancárias, contabilidade e processamento de pagamentos exigem atomicidade e consistência rigorosas.

Transação bancária ACID:
BEGIN;
UPDATE contas SET saldo = saldo - 500 WHERE conta_id = 1001;
UPDATE contas SET saldo = saldo + 500 WHERE conta_id = 1002;
INSERT INTO transacoes (origem, destino, valor, data) 
VALUES (1001, 1002, 500, NOW());
COMMIT;
-- Se qualquer etapa falhar, nada é alterado

Sistemas de reservas: Passagens aéreas, hotéis e salas de concerto precisam evitar duplicidade de reservas.

Aplicações com regras de negócio rígidas: Controle de inventário, pedidos e sistemas ERP que exigem integridade referencial.

6. Quando escolher BASE: cenários de alta escalabilidade

Redes sociais e feeds: Postagens, curtidas e comentários podem ser eventualmente consistentes sem impacto significativo na experiência do usuário.

Arquitetura BASE para feed de notícias:
1. Usuário publica post → escrita em nó primário (rápido)
2. Post é replicado assincronamente para nós secundários
3. Amigos podem ver o post com atraso de alguns segundos
4. Sistema converge para consistência eventual

Sistemas de recomendação: Dados não críticos que podem ser atualizados assincronamente, como sugestões de produtos ou conteúdo personalizado.

Internet das Coisas (IoT): Sensores geram milhões de leituras por segundo, onde dados individuais têm baixa criticidade e o volume exige escalabilidade horizontal.

7. Híbridos e estratégias modernas: NewSQL e bancos multi-modelo

NewSQL: Uma nova geração de bancos que busca unir escalabilidade horizontal com propriedades ACID. Exemplos incluem Google Spanner (que usa relógios atômicos e TrueTime) e CockroachDB (baseado em Raft).

Exemplo conceitual de transação distribuída no CockroachDB:
BEGIN;
UPDATE estoque SET quantidade = quantidade - 1 WHERE produto_id = 42;
INSERT INTO pedidos (cliente_id, produto_id, data) VALUES (101, 42, NOW());
COMMIT;
-- Usa protocolo Raft para garantir consistência entre nós

Transações distribuídas: Protocolos como Two-Phase Commit (2PC) e algoritmos de consenso (Paxos, Raft) permitem transações ACID em sistemas distribuídos, mas com custo de latência.

Abordagem pragmática: Muitas aplicações modernas adotam bancos de dados poliglotas, usando ACID para dados críticos (financeiro, inventário) e BASE para dados de baixa criticidade (logs, analytics, sessões de usuário).

8. Conclusão e melhores práticas

ACID e BASE representam filosofias opostas no design de sistemas de banco de dados. ACID prioriza consistência e integridade, sendo ideal para transações críticas onde erros são inaceitáveis. BASE prioriza disponibilidade e escalabilidade, sendo adequado para sistemas distribuídos de grande escala onde a consistência eventual é tolerável.

Checklist para decisão:
- Os dados precisam ser consistentes imediatamente? → ACID
- O sistema precisa estar disponível 24/7 mesmo com falhas parciais? → BASE
- O volume de transações é muito alto (milhares/segundo)? → BASE
- Existem regras de negócio rígidas (constraints, triggers)? → ACID
- A latência de escrita precisa ser muito baixa? → BASE
- Os dados são financeiros ou críticos? → ACID

Tendências futuras: Bancos de dados poliglotas, sistemas auto-adaptáveis que alternam entre ACID e BASE conforme a carga, e NewSQL continuarão evoluindo para oferecer o melhor dos dois mundos.


Referências