Pular para o conteúdo

apps/data-patterns/two-phase-commit

091 · Dados & Persistência · ≈ 6 min de estudo

Two-Phase Commit (2PC)

Garante que uma transação sobre vários servidores de banco commite em todos ou em nenhum. Na fase 1 cada participante faz sua parte e PREPARE TRANSACTION, votando SIM; o coordenador grava a decisão e, na fase 2, manda COMMIT PREPARED — ou ROLLBACK PREPARED se alguém votou NÃO. O preço: participante que votou SIM fica bloqueado, segurando locks, até ouvir o coordenador.

passos
6
arquivos
7
teste
1
tecnologias
4
Infraestrutura realTypeScriptBunPostgreSQLDocker
Baixar cartão

Cenário

TED entre dois bancos que rodam em servidores diferentes: o débito no Banco A e o crédito no Banco B precisam acontecer juntos. Débito sem crédito é dinheiro sumindo; crédito sem débito é dinheiro criado. E se o coordenador cair no meio, o recovery tem de terminar o que foi decidido.

Planta

Sequência
9/9
alt[algum NÃO][todos SIM]par[fase 1]initiated1UPDATE e PREPARE TRANSACTION2UPDATE e PREPARE TRANSACTION3aborted4ROLLBACK PREPARED5committing - decisão persistida6COMMIT PREPARED7COMMIT PREPARED8committed9coordenador cai após committing: A e B em dúvida, linha travada, até o recoveryCoordenadortpc_transactionsBanco A - débitoBanco B - crédito
9

9 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Commit atômico entre participantes.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    O coordenador registra a transação e dispara a fase 1 em paralelo: cada banco faz o UPDATE e PREPARE TRANSACTION com um GID que carrega o id do coordenador

  2. 02

    Erro no trabalho local — saldo negativo barrado pelo CHECK, conta inexistente — é voto NÃO, desfeito localmente

  3. 03

    Um NÃO bastaaborted no log e ROLLBACK PREPARED em quem preparou

  4. 04

    Todos SIMcommitting é gravado antes de qualquer COMMIT PREPARED — é o ponto sem volta

  5. 05

    Se o coordenador cai depois disso, a transação preparada segura o lock da conta; outro débito espera até dar lock timeout

  6. 06

    O recovery lê pg_prepared_xacts de cada banco: commita o que tem decisão registrada e desfaz o que não tem (presumed abort)

Trade-offs

O que se ganha, o que se paga

3 vantagenscada ganho tem um preço3 custos

Vantagens

  • Atomicidade imediata entre servidores

  • Recovery determinístico pela decisão gravada

  • Sem compensação de negócio

Custos

  • Participante bloqueado enquanto o coordenador não decide

  • Duas rodadas de rede e locks segurados no meio

  • Só com 2 ou 3 participantes que suportam prepare

apps/data-patterns/two-phase-commit

7 arquivos

./

  • docker-compose.ymlinfraCoordenador e dois bancos, cada um num servidor, com max_prepared_transactions

sql/01_coordinator.sql / sql/

  • 01_bank.sqlschemaLog de decisão e contas de cada banco

src/

  • participant_bank.tsPrepare, finalização e listagem das transações em dúvida
  • coordinator_transfer.tsVotação, decisão persistida, fase 2, recovery e plano da TED
  • config_tpc.tsVariáveis de ambiente validadas no boot
  • demo.tsdemoTED confirmada, abortada, em dúvida e recuperada
  • coordinator_transfer.test.tstesteLimite do voto, NÃO do crédito, lock em dúvida e presumed abort contra três servidores reais

Executar · com Docker

  1. docker compose up -d --wait# sobe PostgreSQL
  2. bun install# dependências
  3. bun run demo# roda o cenário
  4. bun run test# integração contra o serviço real
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 · Dados & PersistênciaEventual Consistency
Esc

↑ ↓ navegarEnter abrir191 resultados