sexta-feira, 17 de outubro de 2025

Aplicações Distribuídas - Usando lock distribuído para gerenciar processamento de dados

        Um dos motivos de eu escrever esse Blog, na verdade o principal deles, é eu ter conteúdo pra mim mesmo de uma forma rápida e fácil, pois na nossa área tem coisas que fazemos e depois esquecemos, ou vemos em algum lugar e quando precisamos não conseguimos encontrar. Esse é um desses casos. Essa publicação surgiu de uma palestra que vi do Rafael Ponte no canal da Zup Innovation no youtube que deixo o link no final e aconselho bastante que assistam. Aqui é apenas um resumo para consulta rápida.

         Um problema comum quando trabalhamos com a aplicações distribuídas é quando temos um JOB ou algo do tipo que precisa realizar um determinado processamento de dados e precisamos garantir que esse processamento seja único para cada registro ou linha da tabela.

        Em uma aplicação com uma única instância podemos fazer isso com o synchronized do Java e vida que segue, mas, hoje normalmente trabalhamos com mais de uma instância da aplicação e aí as coisas complicam um pouco. O synchronized resolve para uma única instância mas não tem controle sobre outras execuções, o que nos faz ter que buscar outras soluções.

        Se os dados que precisam ser processados podem ser processados por uma única instância sem criar gargálos, temos por exemplo soluções como:

  •         Eleger um servidor como responsável por executar esse JOB. Essa eu já usei e é bem comum. Pode-se ter uma tabela de parâmetros no banco com o IP de um servidor específico e o JOB checa se o IP cadastrado é o daquela instância, caso seja, ele executa. Pode-se ter uma propriedade no banco (não necessariamente o IP) e outra com mesmo valor em um arquivo de config, ao ler e comparar as duas, sendo iguais, o servidor executa.
  • Usar o próprio banco de dados para gerenciar o lock. Assim, o próprio banco locka os dados enquanto estiverem sendo usados naquela transação. Esse modo basta adicionar uma anotação na consulta:


    
   

        No caso, diretamente no SQL ficaria assim:


        Lembrando que, é preciso garantir que os métos e a atualização sejam eficientes para não locar os registros por muito tempo. Ou seja, o uso do @Transaction precisa ser feito de forma eficiente, ficando apenas a parte necessária da operação dentro da transação. Na Aula o Rafael até mostra uma forma de como fazer isso também.


        Agora, quando os dados precisam ser processados de forma paralela por mais de uma máquina, temos outras soluções a considerar.

  • Uma máquina lê os dados e distribui para as outras processarem. Dependendo do volume de dados e outras variáveis, essa solução era muito usada antes das mensagerias. Uma máquina lê os dados e chama uma outra máquina de uma lista de máquinas disóníveis para executar o processamento. Por exemplo, uma companhia telefônica que precisa realizar o faturamento de clientes tem um JOB que levanta os IDs dos clientes e distribui para outras máquinas processarem o faturamento daqueles clientes. O ponto ruim é que essa "máquina gerente" acumula muita responsabilidade e pode ser um gargalo. Esse trecho de código que levanta os dados só pode rodar em uma única instancia para não duplicar o processamento.
  • Podemos usar soluções de filas e mensagerias. Soluções como Kafka ou outras.
  • Podemos usar o Lock do banco de dados de forma otimizada. Essa é a solução apresentada pelo Rafael. Para isso, acrescenta-se o ao lock do banco a possibilidade de pular os dados locados e pegar o próximo. Vamos ver o que precisa ser adicionado em termos de anotação Java:



        E no SQL diretamente ficaria assim:


        Mais uma vez fica a dica de garantir que o método esteja otimizado, que dentro da tranzação esteja apenas o que precisa estar lá, para que o lock dure apenas o necessário.

        Essa solução é muito interessante porque permite que várias instâncias executem o mesmo código garantindo que os dados serão respeitados por todas elas como mostra a imagem abaixo:



        Aqui temos todo o código de exemplo trazido por ele na aula:



        Aconselho assistir a aula, tem mais coisas interesantes lá!


Link: aula do Rafael Ponte sobre Distributed Scheduling





Nenhum comentário:

Postar um comentário