Pular para o conteúdo principal

Shared Database

Descrição​

No padrão Shared Database, todos os serviços utilizam um único banco de dados. Cada serviço pode ler e gravar diretamente em dados pertencentes a outros serviços, aproveitando transações ACID locais. Por exemplo, o serviço de pedidos pode executar uma única transação que lê o limite de crédito e o total de pedidos em aberto do cliente e, em seguida, insere o novo pedido, com o banco garantindo que o limite não seja ultrapassado, mesmo com pedidos concorrentes.

Em microsserviços, esta abordagem é geralmente considerada um anti-padrão, porque o esquema de dados se torna um contrato implícito entre todos os serviços. Ela é descrita no catálogo como a alternativa que contrasta com Database per Service e é útil sobretudo para entender o que se perde (e o que se ganha) ao adotar bancos privados.

Na visão do Enterprise Integration Patterns (Hohpe e Woolf), Shared Database é um dos quatro estilos de integração: as aplicações trocam informação gravando em um único banco. Como todas enxergam os mesmos dados quase ao mesmo tempo, a consistência é alta, o gerenciamento de transações lida com atualizações concorrentes e os erros são mais fáceis de rastrear. A maior dificuldade é projetar um esquema único que atenda bem a várias aplicações, e a pressão política de times que não querem esperar por um esquema unificado costuma levar à fragmentação.

Problemas que resolve​

  • Invariantes de negócio que atravessam serviços (como respeitar o limite de crédito ao criar um pedido) exigem consistência forte, e transações ACID resolvem isso de forma simples.
  • Consultas que cruzam dados de vários serviços (disponibilidade de crédito, clientes de uma região com seus pedidos recentes) são resolvidas com joins comuns.
  • Operar um único banco é mais simples do que operar vários.

Quando usar​

  • Em aplicações pequenas ou em transição a partir de um monólito, em que poucos times compartilham o mesmo domínio.
  • Quando a consistência forte entre os dados é um requisito inegociável e a autonomia dos serviços é secundária.

Quando evitar​

  • Quando a implantação e a evolução independentes dos serviços são objetivos da arquitetura.
  • Quando serviços têm requisitos de armazenamento ou de escala muito diferentes.
  • Quando várias equipes alteram o esquema com frequência.

Trade-offs​

GanhoCusto / Risco
Transações ACID familiares garantem consistência dos dadosAcoplamento em tempo de desenvolvimento: mudanças de esquema exigem coordenação entre todas as equipes que usam as tabelas
Um único banco é mais simples de operarAcoplamento em tempo de execução: uma transação longa de um serviço pode bloquear tabelas e travar outro
Consultas com joins entre domínios são triviaisUm único banco pode não atender às necessidades de armazenamento de todos os serviços
  • Escala: o banco compartilhado vira ponto único de contenção e de falha; replicação e sharding afetam todos os serviços ao mesmo tempo.
  • Evolução: o esquema se torna difícil de mudar, e a propriedade dos dados fica ambígua.

Diagrama​

Todos os serviços leem e gravam no mesmo banco, o que simplifica transações e consultas, mas cria acoplamento forte pelo esquema compartilhado.

Padrões relacionados​

Referência​