Concorrência e isolamento
Escalonamentos, serialização, leituras sujas, fantasmas, atualizações perdidas e snapshots.
Anomalias a reconhecer
Um escalonamento intercala operações respeitando a ordem interna de cada transação. É serial se uma acaba antes da seguinte; serializável se equivale a alguma ordem serial.
| Anomalia | Sinal a detetar |
|---|---|
| Atualização perdida | Duas leituras de 10 e duas escritas de 9: duas vendas, uma unidade retirada. |
| Leitura suja | Usa valor ainda não confirmado, depois anulado por rollback. |
| Leitura não repetível | A mesma linha muda entre duas leituras, por commit alheio. |
| Fantasma | O conjunto que satisfaz o predicado muda entre contagens. |
SET stock = stock - 1 WHERE stock >= 1, conferindo linhas afetadas, evita o padrão ler-calcular-escrever no cliente. Regras entre várias linhas pedem proteção própria.
Testar por conflitos
Duas operações de transações diferentes conflitam se tocam no mesmo item e pelo menos uma escreve. No grafo, quando a operação de precede a conflitante de .
Acíclico se e só se serializável por conflitos; uma ordem topológica dá a ordem serial equivalente. O critério é mais restrito que outras equivalências por observação.
r1(X), r2(X), w1(X), w2(X) tem ciclo; r1(X), w1(X), r2(X), w2(X) só exige T1 antes de T2.
Mecanismos e limites
- Bloqueio em duas fases: adquire tudo antes de começar a libertar; sob as hipóteses, garante serializabilidade por conflitos. Deadlock (T1 segura A espera B; T2 o inverso) pede deteção e repetição da transação inteira com leituras novas.
- MVCC: versões para snapshots coerentes sem bloquear todas as escritas. Snapshot estável não prova serializabilidade.
Não foi possível carregar a animação. Abre o vídeo ou acompanha a descrição abaixo.
Write skew quebra uma regra entre linhas sem leitura suja nem escrita sobreposta: protege o conjunto com isolamento serializável e repetição, ou bloqueios que cubram a regra. Bloquear só a linha alterada pode não bastar.
O que cada motor dá
Os nomes SQL proíbem sujas (Read committed), sujas e não repetíveis (Repeatable read), e ainda fantasmas (Serializable). Evitar as três não prova serializabilidade total; o motor pode dar mais que o mínimo.
- PostgreSQL: Read committed com snapshot por instrução. Repeatable read com snapshot estável, sem os fantasmas descritos, mas admite write skew. Serializable aborta em conflito de serialização; repete tudo.
SELECT ... FOR UPDATEbloqueia linhas, sem provar regras genéricas. - SQLite: um escritor de cada vez. Em WAL, leitores mantêm snapshots durante escritas. Promover leitura antiga a escrita pode falhar com
SQLITE_BUSY_SNAPSHOT; termina e repete.BEGIN IMMEDIATEreserva cedo a escrita. Entre ligações, impede leituras não confirmadas;read_uncommittedem cache partilhada é a exceção. Uma só ligação não demonstra concorrência.
