Pular para o conteúdo

apps/patterns/two-phase-commit

031 · Padrões Fundamentais · ≈ 6 min de estudo

Two-Phase Commit

Garante que uma transação sobre vários bancos de dados commita em todos ou em nenhum. Na fase 1 cada banco executa sua parte e faz PREPARE TRANSACTION, votando SIM; na fase 2 o coordenador persiste a decisão e manda COMMIT PREPARED, ou ROLLBACK PREPARED se alguém votou NÃO. Use com 2 ou 3 participantes que suportam prepare, quando compensação de saga não serve.

passos
6
arquivos
7
teste
1
tecnologias
5
Infraestrutura realTypeScriptBunElysiaPostgreSQLDocker
Baixar cartão

Cenário

Uma transferência entre dois bancos, cada um com seu próprio banco de dados (bank_a e bank_b). R$ 500,00 para uma conta ativa: os dois votam SIM e commitam. R$ 200,00 para uma conta bloqueada: o banco B vota NÃO e o banco A desfaz o débito que já tinha preparado. R$ 300,00 com o coordenador parando logo depois de decidir: as duas transações ficam preparadas, segurando o lock da conta, até o recovery completar o commit.

Planta

Sequência
7/7
BEGIN, UPDATE, PREPARE TRANSACTION gid_a1BEGIN, UPDATE, PREPARE TRANSACTION gid_b2SIM3SIM4grava decisão committing5COMMIT PREPARED gid_a6COMMIT PREPARED gid_b7coordenador caiu antes da fase 2: recovery lê pg_prepared_xacts e a decisão gravadaCoordenadortpc_decisionsBanco A (débito)Banco B (crédito)
7

7 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Prepara todos, confirma por unanimidade.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    Fase 1Cada participante roda BEGIN, sua escrita e PREPARE TRANSACTION; a transação sobrevive à sessão e segura os locks

  2. 02

    VotoErro na escrita (saldo insuficiente, conta bloqueada) é voto NÃO, com ROLLBACK local

  3. 03

    UnanimidadeUm NÃO basta para ROLLBACK PREPARED em quem preparou

  4. 04

    Decisão persistidaCom todos SIM, tpc_decisions recebe committing antes de qualquer COMMIT PREPARED

  5. 05

    RecoveryNo restart, cada gid em pg_prepared_xacts é commitado se tem decisão e desfeito se não tem (presumed abort)

  6. 06

    Pré-requisitomax_prepared_transactions é 0 por padrão; o docker.sh sobe o PostgreSQL com 100

Trade-offs

O que se ganha, o que se paga

3 vantagenscada ganho tem um preço3 custos

Vantagens

  • Atomicidade imediata entre bancos

  • Sem janela de inconsistência

  • Recovery determinístico pela decisão

Custos

  • Locks seguros do prepare até a fase 2

  • Coordenador fora do ar bloqueia os participantes

  • Prático só com 2 ou 3 participantes

apps/patterns/two-phase-commit

7 arquivos

sql/

  • 01_schema.sqlschemaBanco do coordenador com tpc_decisions e os bancos bank_a e bank_b

src/

  • coordinator_transfer.tsAs duas fases, a decisão persistida e o recovery por pg_prepared_xacts
  • participant_transfer.tsDébito no banco A e crédito no banco B
  • config_transfer.tsLê e valida o ambiente no boot
  • coordinator_transfer.test.tstesteIntegração contra PostgreSQL real: commit, voto NÃO, fronteira do saldo, lock após o prepare e recovery
  • demo.tsdemoTrês transferências e o recovery depois da queda do coordenador

./

  • docker.shinfraSobe o PostgreSQL com transações preparadas habilitadas

Executar · com Docker

  1. ./docker.sh up# sobe PostgreSQL
  2. cp .env.example .env# variáveis de ambiente
  3. bun install# dependências
  4. bun run demo# roda o cenário

Testes: bun run test.

Requisitos
BunDocker
Sobe junto
PostgreSQL

Por que se relacionam

Teste rápido

Qual é o próximo passo depois de Two-Phase Commit?

Próximo projeto · Arquiteturas de Alto Nível (Macro-Architecture)Arquitetura Monolítica
Esc

↑ ↓ navegarEnter abrir191 resultados