E-commerce com Next.js
Como gerenciar estoque e invalidação de cache em uma loja Next.js
Evite vendas acima do estoque com estoque transacional, reservas, webhooks idempotentes, tags de cache Next.js, invalidação específica e testes de concorrência.
Estoque é uma transação, não um valor em cache. O cache informa o que estava disponível recentemente; somente a gravação na fonte de verdade pode prometer a última unidade.
Definir disponível, reservado e vendido
Trail Supply tem dois Alpine Shell azuis de tamanho médio. onHand é a quantidade física, reserved é o que está temporariamente reservado por checkouts ativos e sold pertence a pedidos confirmados. A disponibilidade deriva desses estados duráveis, em vez de ser um número independente que possa ficar inconsistente.
Defina quando a reserva começa, quanto dura e qual evento a confirma ou libera. Reservar ao adicionar ao carrinho costuma ser cedo demais; reservar no Checkout pode servir a estoques limitados; reservar no pagamento exige uma política para compradores simultâneos.
Faça a mudança de estoque atômica
Uma sequência de leitura seguida de gravação permite que duas requisições vejam a mesma última unidade. Use transação, bloqueio de linha, atualização condicional ou outra operação atômica compatível com o armazenamento. A gravação só tem sucesso se ainda houver estoque não reservado suficiente.
Imponha quantidades não negativas com restrições no banco quando possível. Registre reserva, variante, quantidade, proprietário ou pedido pendente, criação, expiração e status na mesma transação que altera a disponibilidade.
const reserved = await db.inventory.updateMany({
where: {
variantId,
available: { gte: quantity },
},
data: {
available: { decrement: quantity },
reserved: { increment: quantity },
},
});
if (reserved.count !== 1) {
return { error: "Insufficient stock" };
}Expirar deliberadamente as reservas
Armazene a expiração e execute uma tarefa agendada de recuperação que libere reservas ativas cuja Checkout Session não possa mais concluir. A liberação deve ser idempotente: uma reserva já confirmada ou liberada não deve mudar.
Eventos atrasados precisam de uma política. Se o pagamento concluir após a expiração local, concilie o estado do provedor e do processamento do pedido em vez de recriar estoque ou cancelar um pedido pago sem verificação. Algumas lojas permitem pedidos pendentes por falta de estoque; outras reembolsam. Implemente a decisão do produto.
Invalidar o menor conjunto correto
Após alterar estoque ou preço, invalide o produto e cada categoria que exiba o valor alterado. updateTag permite ao usuário da Server Action ver a própria gravação; revalidateTag com um perfil adequado serve ao conteúdo que pode mostrar dados antigos durante a atualização.
Não limpe todas as páginas da loja em cache quando uma jaqueta azul média mudar. Invalidações amplas aumentam a carga e dificultam entender o cache. Centralize a criação das tags para que publicação, webhooks e ações administrativas usem os mesmos nomes.
Conciliar eventos do armazém e dos pagamentos
Registre IDs de eventos externos antes de alterar o estoque. Ajustes do armazém, cancelamentos, reembolsos e pagamentos concluídos podem se repetir ou chegar fora de ordem. Normalize cada evento como transição local de estoque e rejeite transições incompatíveis com o estado atual.
Mantenha um registro de movimentos somente com acréscimos ou um histórico de auditoria suficiente para explicar o total. Corrigir a quantidade atual sem o histórico de reservas e pedidos é difícil após uma falha de provedor ou implantação.
Testar disputa por estoque e recuperação sob carga
Envie muitas reservas simultâneas para as últimas duas unidades e verifique se no máximo duas têm sucesso. Interrompa um worker, repita um pagamento, expire uma reserva, entregue uma conclusão atrasada e reconstrua a visão do produto em cache. Verifique as invariantes do banco e os resultados visíveis aos clientes.
Execute esses testes contra a compilação de produção em uma prévia Adios. Os logs de execução revelam disputas por recursos e erros de webhook, enquanto banco e segredos obrigatórios ficam explícitos no manifesto. Promova a versão após a rota de saúde e os testes básicos de estoque passarem.