[Dúvida] Node.JS + Express - Melhor maneira de lidar com requisições duplicadas e simultâneas?
Olá devs :)
Senta que lá vem história haha
Talvez seja uma dúvida óbvia, mas apenas para contextualizar, a equipe em que eu trabalho esta migrando aos poucos de tecnologia, pegando novos projetos pequenos para ganharmos confiança e migrarmos totalmente assim que possível, nunca tabalhamos com elas antes, então estamos desenvolvendo juntamente com uma fase de aprendizado.
Estamos utilizando a seguinte stack para o backend:
Node.JS
+ Express
+ TypeScript
+ Prisma
+ PostgreSQL
Existem outras bibliotecas, mas como não estão envolvidas no problema, acredito que não seja necessário citar, além disso, estamos tentando aplicar boas práticas de padrão de projeto (SOLID, DDD e etc).
Contexto da funcionalidade:
O operador deve realizar a leitura do código de barra de um item, essa leitura cria o registro do item no local atual do operador (informado anteriormente) e indica onde o mesmo deve levar o item para ser armazenado, criando uma ordem de armazenagem (responsável por medir produtividade).
Durante a execução do meu serviço, eu verifico se o usuário já não realizou a leitura do item, caso sim, eu somente devolvo para o frontend a ordem de armazenagem que já foi criada anteriormente, evitando a duplicidade de saldo e ordens de armazenagem.
Fluxo super resumido realizado no sistema:
- Frontend dispara uma requisição POST informando o código do produto
- O Express "recebe" a REQUEST e chama a minha rota, vamos chama-la de /stock/read-item
- Minha rota chama meu CONTROLLER -> Extrai os dados da requisição necessário para chamar o serviço (Usuário logado, código do produto, etc).
- Meu CONTROLLER chama meu SERVICE, repassando as variaveis extraidas no passo anterior
- Meu SERVICE executa as regras de negócio baseado no contexto que expliquei acima e retorna para o CONTROLLER a ordem de armazenagem.
- CONTROLLER devolve a ordem de armazenagem na RESPONSE da requisição para que seja utilizada pelo frontend
Problema:
Por algum motivo, estou recebendo duas requisições referente a leitura do item em um período muito curto de tempo (realmente curto).
Requisição 1: 2023-12-08 14:07:42.130
Requisição 2: 2023-12-08 14:07:42.134 (00:00:00:004 milissegundos de diferença)
O problema, é que como ambas as requisições são praticamente simultâneas, a consulta no banco de dados para verificar se o item já foi lido anteriormente, também é simultânea, onde em ambas as consultas, é retornado para o serviço que o item ainda não foi lido.
Como o item "não foi lido", também não existe ordem de armazenagem e assim, eu chamo meu outro serviço responsável por criar o item e a ordem de armazenagem em ambas as requisições, duplicando o saldo :(
Realizei uma solução do jeitinho brasileiro, mas gostaria de saber, qual a solução de vocês para esses cenários? Não acredito que seja o usuário, então acredito que o navegador dele esta duplicando as requisições de alguma maneira.
Observação: Ocorreu 4x em 6 meses no ambiente produtivo, já foram lidos mais de 100 mil produtos, sei que não é muito, mas gostaria de tratar da maneira correta para que isso seja aplicado em todos os novos projetos :)
Agradeço quem leu até aqui, mesmo que seja de curiosidade para entender como realizar essa tratativa também no seu próprio projeto <3
@Edit
Obrigado a todos pelas sugestões.
Realizei a implementação com Redis e funcionou perfeitamente em nossas simulações, irei estudar se consigo fazer algo de maneira global agora :)
Obrigado especial ao @founty, @uriel e @tokyo por terem sugerido essa implementação.