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.

G-DL

Ciclo de Deadlock & Recuperação

Dois workers de transferência bloqueiam contas em ordem inversa, induzindo um deadlock no grafo de espera (WFG).

Dois workers de transferência bloqueiam contas em ordem inversa, induzindo um deadlock no grafo de espera (WFG).

Schema e dados iniciais

schema.sql & seed.sql
-- Schema
CREATE TABLE accounts (
    id INT PRIMARY KEY,
    balance INT NOT NULL
);

-- Seed
INSERT INTO accounts VALUES (1, 500), (2, 500);

Carga concorrente (chaos.yaml)

chaos.yaml
version: "1.0"
name: "deadlock_cycle_recovery"
operations:
  - name: "transfer_1_to_2"
    steps:
      - "SELECT balance FROM accounts WHERE id = 1 -> b1"
      - "UPDATE accounts SET balance = balance - 100 WHERE id = 1"
      - "UPDATE accounts SET balance = balance + 100 WHERE id = 2"
  - name: "transfer_2_to_1"
    steps:
      - "SELECT balance FROM accounts WHERE id = 2 -> b2"
      - "UPDATE accounts SET balance = balance - 100 WHERE id = 2"
      - "UPDATE accounts SET balance = balance + 100 WHERE id = 1"
invariants:
  - name: "total_balance_exact"
    query: "SELECT sum(balance) AS total FROM accounts;"
    assert: "total == 1000"

Por que a invariante quebra

T1 trava a Conta 1 e requisita trava na Conta 2. Concorrentemente, T2 trava a Conta 2 e requisita trava na Conta 1. A espera mútua induz um ciclo no Wait-For Graph (WFG).

T1 ──(waits)──► T2 ──(waits)──► T1

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

Correção em produção

Ordenação Canônica Determinística de Bloqueios (Lock Ordering)

Deadlocks ocorrem quando diferentes transações disputam os mesmos registros em ordens inversas (T1: 1 depois 2; T2: 2 depois 1). A mitigação canônica consiste em estabelecer um protocolo estrito de ordenação hierárquica de recursos antes de adquirir qualquer bloqueio (ex: travar sempre pelo menor ID primeiro). Com ordenação canônica garantida na camada de repositório, ciclos no Wait-For Graph tornam-se matematicamente impossíveis de se formarem.

✓ PostgreSQL (Code 40P01)✓ MySQL (Error 1213), SQLite

PostgreSQL (Code 40P01), MySQL (Error 1213), SQLite

remediation_fix.sql
-- Ordenação Padronizada de Locks pelo Menor ID
-- Na aplicação:
-- first_id = MIN(conta_a, conta_b)
-- second_id = MAX(conta_a, conta_b)

BEGIN;
-- Bloquear sempre os recursos na mesma ordem canônica crescente:
SELECT id, balance FROM accounts WHERE id = :first_id FOR UPDATE;
SELECT id, balance FROM accounts WHERE id = :second_id FOR UPDATE;

UPDATE accounts SET balance = balance - 100 WHERE id = :origem;
UPDATE accounts SET balance = balance + 100 WHERE id = :destino;
COMMIT;