Design clássico · Pleno
E-commerce: catálogo, carrinho e checkout
Projeto de entrevista clássico. Pontos centrais: reservas e concorrência.
Resposta curta
Projeto de entrevista clássico. Pontos centrais: reservas e concorrência. O exercício clássico de e-commerce pede um catálogo de produtos, um carrinho e um checkout. Este caso se concentra no checkout, o momento em que uma única ação do cliente precisa alterar três conjuntos de dados: o pedido, o estoque e o pagamento. Catálogo e carrinho aparecem apenas como contexto.
01 · CONTEXTO
Um clique, três donos de dados
O exercício clássico de e-commerce pede um catálogo de produtos, um carrinho e um checkout. Este caso se concentra no checkout, o momento em que uma única ação do cliente precisa alterar três conjuntos de dados: o pedido, o estoque e o pagamento. Catálogo e carrinho aparecem apenas como contexto.
Arquiteturas de microsserviços costumam dar a cada serviço um banco dedicado. Quando pedidos e clientes ficam em bancos de serviços diferentes, a aplicação não consegue usar uma simples transação ACID local. A fonte ilustra o problema com uma loja virtual em que o cliente tem um limite de crédito.
02 · PONTO DE PARTIDA
Um banco, uma transação
Com um único banco a vida é simples. Dentro de um único serviço, as transações seguem os princípios ACID porque operam sobre um só banco, e a atomicidade significa que todas as operações têm sucesso ou nenhuma tem. Gravar o pedido e baixar o estoque na mesma transação garante, portanto, que os dois acontecem ou nenhum acontece.
O cliente confirma a compra; a requisição passa pela API da loja e chega à aplicação.
A aplicação abre uma transação local no banco único.
Dentro da mesma transação ela grava o pedido e baixa o estoque, e as duas mudanças são confirmadas juntas.
Se algo falha no meio, nenhuma das duas mudanças vale e o banco desfaz tudo.
03 · SEPARANDO
Quando cada serviço tem o seu banco
Dividir em serviços traz ganhos que a documentação da Microsoft enumera: cada serviço encapsula os seus dados e as falhas em um serviço ficam isoladas dos outros. O preço é que garantias como ACID não se aplicam diretamente a vários bancos geridos de forma independente.
O cliente confirma a compra e a API encaminha o pedido ao serviço de pedidos.
O serviço de pedidos grava o pedido no seu próprio banco, numa transação local.
Em seguida o serviço de pedidos chama o serviço de estoque, que baixa a quantidade no banco dele.
Depois chama o serviço de pagamentos e, neste cenário, a cobrança não se completa.
Pedido e estoque já foram confirmados nos seus bancos, e não existe rollback automático que atravesse os três serviços: é preciso desfazer o que foi feito de forma explícita.
04 · SAGA
Passos locais e compensações
A resposta clássica é a saga: uma sequência de transações locais coordenada de forma confiável. Se um passo falha por violar uma regra de negócio, as mudanças dos passos já concluídos são desfeitas por transações compensatórias.
Há duas formas de coordenar a saga. Na coreografia, cada transação local publica eventos de domínio que disparam transações locais em outros serviços. Na orquestração, um orquestrador diz aos participantes quais transações locais executar.
| Aspecto | Coreografia | Orquestração |
|---|---|---|
| Como coordena | Cada serviço publica eventos que disparam os passos dos outros | Um orquestrador diz aos participantes o que executar |
| Quando serve | Fluxos simples, com poucos serviços | Fluxos complexos ou que ganham novos serviços |
| Ponto fraco | O fluxo pode ficar confuso quando se acrescentam passos | O orquestrador é um ponto de falha, pois gerencia o fluxo inteiro |
A fonte descreve o pedido assim: o serviço de pedidos recebe o POST /orders e cria o pedido em estado PENDING; o serviço de clientes tenta reservar crédito; e o tratador de eventos do serviço de pedidos aprova ou rejeita o pedido.
O serviço de pedidos recebe a compra e cria o pedido em estado pendente; na mesma transação local grava a mensagem que precisa ser enviada.
Um processo separado lê a caixa de saída e envia a mensagem ao broker.
O serviço de estoque recebe a mensagem e tenta reservar os itens numa transação local, do mesmo modo que o exemplo da fonte tenta reservar crédito.
Com a reserva feita, o serviço de pagamentos tenta a cobrança; neste cenário ela é recusada por saldo insuficiente, uma falha esperada e não um erro inesperado.
A falha chega ao serviço de estoque, que executa a transação compensatória e libera a reserva feita antes.
Por fim o serviço de pedidos recebe o resultado e rejeita o pedido, em vez de aprová-lo.
A saga tem custos. Não há rollback automático, então o desenvolvedor precisa projetar as transações compensatórias que desfazem o que foi feito. E falta isolamento entre sagas concorrentes: é preciso análise cuidadosa para escolher e implementar contramedidas. Além disso, as compensações podem não ter sucesso e deixar o sistema inconsistente.
05 · MENSAGEM CONFIÁVEL
Gravar e publicar sem perder nada
Para a saga funcionar, o serviço precisa atualizar o banco e enviar a mensagem de forma atômica, senão surgem inconsistências. Uma transação distribuída que abranja banco e broker não é viável. Sem ela, enviar a mensagem no meio da transação não dá garantia de que ela será confirmada, e enviar depois do commit não garante que o serviço não cairá antes do envio.
A saída é a caixa de saída transacional: o serviço grava a mensagem no banco, na mesma transação que atualiza as entidades de negócio, e um processo separado a envia ao broker de mensagens.
Esse relay pode publicar a mesma mensagem mais de uma vez, por exemplo se cair depois de publicar e antes de registrar que publicou. Por isso o consumidor precisa ser idempotente, por exemplo registrando os identificadores das mensagens já processadas.
Como a saga é um fluxo assíncrono, quem iniciou a compra por uma requisição síncrona precisa descobrir o resultado depois. Uma das opções da fonte é devolver o identificador do pedido e deixar o cliente consultar periodicamente o estado.
06 · PAGAMENTO
Cobrar uma vez, mesmo com falhas
O pagamento é o passo em que o erro mais custa. A meta descrita pela Shopify é que a cobrança aconteça exatamente uma vez apesar de repetições de requisição. A chave de idempotência encontra os passos que a tentativa já concluiu, e garante que seja enviado um único pedido ao parceiro financeiro.
O serviço de pedidos pede a cobrança enviando uma chave única para a tentativa.
O serviço de pagamentos registra a tentativa no banco local, um dos passos que a chave permite reencontrar.
O serviço chama o parceiro financeiro com timeouts baixos para não ficar esperando indefinidamente.
Se a chamada falha por rede, o pedido pode ser repetido com a mesma chave, e o parceiro recebe uma única requisição.
Um job de reconciliação compara os registros locais com os do parceiro e, quando há divergência, registra a anomalia no banco.
Dentro da saga, o Azure Architecture Center chama de transação pivô o ponto sem volta. Depois dele vêm transações repetíveis e idempotentes, que ajudam a saga a chegar ao estado final mesmo com falhas temporárias.
07 · PICO E ISOLAMENTO
Proteger o checkout e fechar as brechas
Sob pico, a Shopify usa balanceadores programáveis para limitar a quantidade de checkouts simultâneos. Se há mais compradores querendo pagar do que a capacidade comporta, eles esperam numa fila antes de pagar.
Resta o isolamento. Falta isolamento entre sagas concorrentes, e a documentação da Microsoft lista anomalias como atualizações perdidas e leituras sujas, estas quando uma saga lê dados que outra modificou sem concluir. Uma das contramedidas é reler os valores antes de atualizar.
Perguntas frequentes
O que é E-commerce: catálogo, carrinho e checkout?
Projeto de entrevista clássico. Pontos centrais: reservas e concorrência.
O que o design de E-commerce: catálogo, carrinho e checkout cobre?
Ele está organizado nestas seções: Um clique, três donos de dados, Um banco, uma transação, Quando cada serviço tem o seu banco, Passos locais e compensações, Gravar e publicar sem perder nada e Cobrar uma vez, mesmo com falhas.
Quanto tempo leva E-commerce: catálogo, carrinho e checkout e qual é o nível?
Leva cerca de 14 minutos para ler e tem nível Pleno.
Agora projete você mesmo
Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.