ChaosSQL

Catálogo de Concorrência

Cenários Canônicos & Mitigações

Explore 10 cenários de falhas de concorrência baseados em pesquisas acadêmicas de isolamento e casos reais de sistemas financeiros e distribuídos.

G0

Escrita Suja em Leilão (Dirty Write)

Dois licitantes concorrentes sobrescrevem colunas distintas da mesma linha de leilão sem bloqueios 2PL estritos.

Dois licitantes concorrentes sobrescrevem colunas distintas da mesma linha de leilão sem bloqueios 2PL estritos.

Schema e dados iniciais

schema.sql & seed.sql
-- Schema
CREATE TABLE auctions (
    id INT PRIMARY KEY,
    item TEXT NOT NULL,
    highest_bid INT NOT NULL,
    winner TEXT NOT NULL
);

-- Seed
INSERT INTO auctions VALUES (1, 'Rare Stamp', 100, 'Original');

Carga concorrente (chaos.yaml)

chaos.yaml
version: "1.0"
name: "auction_dirty_write"
operations:
  - name: "bid_alice"
    steps:
      - "UPDATE auctions SET highest_bid = 150 WHERE id = 1"
      - "UPDATE auctions SET winner = 'Alice' WHERE id = 1"
  - name: "bid_bob"
    steps:
      - "UPDATE auctions SET highest_bid = 200 WHERE id = 1"
      - "UPDATE auctions SET winner = 'Bob' WHERE id = 1"
invariants:
  - name: "bid_winner_consistency"
    query: "SELECT highest_bid, winner FROM auctions WHERE id = 1;"
    assert: "(highest_bid == 150 AND winner == 'Alice') OR (highest_bid == 200 AND winner == 'Bob')"

Por que a invariante quebra

Sem travas atômicas ou updates em instrução única, Alice escreve lance 150, Bob escreve lance 200, mas o segundo passo de Alice grava vencedor='Alice', criando um estado inconsistente: lance de $200 vencido por Alice.

T1 ──(ww)──► T2 ──(ww)──► T1

Delta debugging reduz 15 operações às 2 que causam a falha.

Correção em produção

Atualização Atômica Multi-Coluna com Predicado Monotônico

Dirty Writes (G0) ocorrem quando escritas não comitadas de transações simultâneas se entrelaçam sobre a mesma linha de dados. A correção definitiva consiste em unificar as atualizações de valor e titular em uma única cláusula UPDATE atômica no banco, condicionada estritamente a um lance superior ao atual (WHERE id = 1 AND highest_bid < novo_lance). Isso assegura retenção de locks 2PL estritos e garante monotonicidade sem risco de estados corrompidos híbridos.

✓ PostgreSQL✓ SQLite✓ MySQL

PostgreSQL, SQLite, MySQL

remediation_fix.sql
-- Update Atômico em Instrução Única com Cláusula Monotônica
BEGIN;
UPDATE auctions 
SET highest_bid = 200, 
    winner = 'Bob' 
WHERE id = 1 AND highest_bid < 200;

-- Se rows_affected == 0, o lance já foi superado concorrentemente;
-- Fazer ROLLBACK e notificar o usuário.
COMMIT;