Aplicações corporativas
muitas vezes são construídas para lidar com processos que envolvem grandes
volumes de dados. Neste cenário, é normal que apareça a necessidade de
desenvolvimento de processos em lote. Por causa disso, é importante para todos
os desenvolvedores Java conhecer a API que se tornará a padrão para a criação
de processos desse tipo.
Autores: Renan
de Melo Oliveira, Julien
Renaut e Marcelo Takeshi Fukushima
O desenvolvimento de software permitiu que diversas tarefas antes consideradas impossíveis se tornassem não só possíveis, mas também viáveis. Vivemos na era da informação onde o acesso a uma quantidade de dados virtualmente infinita está ao alcance de um clique. Hoje podemos realizar transferências bancárias entre diferentes bancos que são finalizadas em minutos, falar com voz e vídeo com um grupo de dezenas de pessoas distribuídas no mundo inteiro e realizar cálculos com uma velocidade surpreendente. No entanto, computacionalmente falando, manipular tamanha quantidade de dados é um desafio.
No mercado de aplicações corporativas é comum a necessidade de lidar com volumes massivos de dados. Processar manualmente estes dados é repetitivo e burocrático, gerando assim pouco valor para as empresas. No entanto, com os avanços obtidos nos últimos anos, tanto em hardware como software, hoje é possível automatizar muitos destes processos de forma a diminuir custos e aumentar a confiabilidade das informações extraídas.
Atualmente, uma das necessidades mais comuns em grandes operações de software é o desenvolvimento de processos batch (em lote). Processos batch são operações realizadas por um sistema que não necessitam de interação direta com o usuário. Estes processos são caracterizados por lidarem com um grande volume de dados e normalmente são executados em um período diferente do horário comercial – durante a madrugada por exemplo. Diversos fatores relacionados às áreas de negócio destas empresas justificam essa necessidade, como a integração com outros sistemas, sumarização de operações financeiras realizadas durante o dia, ou mesmo limpezas periódicas.
A versão mais recente da Java Enterprise Edition (Java EE 7) incluiu a JSR 352 (Batch Applications for the Java Platform), uma biblioteca para desenvolvimento de processos em lote de forma fácil e padronizada. Esta API permite definir, executar e acompanhar processos batch em um container compatível como o GlassFish 4.
Neste artigo, iremos implementar um processo batch para simular o fechamento de faturas de um sistema bancário, o FaturaWeb. O processo será composto por algumas etapas como conversão de valores em dólar e totalização dos lançamentos para uma fatura. Para isso, usaremos algumas das funcionalidades básicas da API, como a definição de uma tarefa e seus componentes, assim como o disparo e acompanhamento do processo como um todo.
Necessidades e problemas de processos em lote
Para compreendermos as vantagens desta API da forma como foi proposta, é importante avaliarmos os problemas inerentes de processos batch. Esta reflexão é essencial para sabermos como lidar melhor com este tipo de operação.
Um processo em lote, como já foi dito, é caracterizado por não necessitar de interação com o usuário, podendo ser executado de forma assíncrona. Uma operação assíncrona não exige que o componente chamador espere o término da execução para prosseguir com o restante das instruções. Desta forma, uma operação assíncrona pode realizar um processamento demorado sem que isto impacte a experiência do usuário, pois o mesmo não ficará “travado” esperando a resposta da operação. Além disso, ao contrário do caso síncrono, a partir do momento em que o usuário requisita ou agenda a execução de um processo em lote, o mesmo perde o contato direto com a execução deste, dificultando o acompanhamento e a administração da tarefa.
No entanto, por serem assíncronos e normalmente demorados, é importante permitir que o usuário possa monitorar o andamento dos processos batch. Essa importância também se aplica em casos em que ocorrem erros por conta de pré-condições externas não satisfeitas, como a falta de dados oriundos de fontes externas, ou mesmo falhas de rede e quedas de energia. Para contornar tais problemas, a API permite que processos com erro possam ser reiniciados, seja do início ou do ponto onde pararam.
Igualmente importante é saber se um processo batch foi concluído antes de se realizar alguma operação de negócio. Por exemplo, o cálculo do valor da cota de um fundo de investimento é fundamental para determinar o valor disponível para resgate de um cliente. Portanto, enquanto o processo batch responsável pelo cálculo desta cota não terminar, o investidor não poderá realizar o resgate.
O controle transacional dos processos em lote também demanda um planejamento cuidadoso. Há casos em que a tarefa inteira deva ser executada em uma transação única e também casos em que commits parciais devam ser realizados durante a operação.
Além do que já foi citado, também é desejável que os recursos computacionais do ambiente sejam corretamente utilizados, sejam eles diversos núcleos de processamento ou diversas máquinas em um cluster. Porém, pode não ser trivial lidar com processamento paralelo no contexto de processos em lote, pois muitas vezes queremos que apenas parte de um processo seja executada em paralelo, enquanto outras partes precisam ser executadas de forma sequencial.
Em resumo, quando desenvolvemos processos batch nos deparamos com diversas necessidades e problemas. A seguir começaremos o detalhamento da API de processos batch mostrando como os requisitos listados são supridos.
Funcionamento básico da API
A API de batches nos permite definir tarefas (jobs). Cada job representa a configuração de um processo em lote e descreve de forma geral qual é o conjunto de etapas (steps) que devem ser realizadas durante a execução deste processo. Mais à frente iremos explicar mais detalhadamente como desenvolver uma aplicação batch, porém, de forma geral, esta API nos possibilita realizar as seguintes operações:
· Definição de tarefas (jobs), etapas (steps) e elementos de decisão (decisions) em nossas aplicações, sendo um processo batch representado por um job, que por sua vez consiste em um conjunto de steps inter-relacionados;
· Definição de um processo batch por meio de um fluxo completo de passos em um arquivo de configuração;
· Informação de status para cada execução de processo;
· Execução de processos e a continuação de processos interrompidos por meio de um controlador unificado;
· Tratamento de erros;
· Possibilidade de processamento paralelo de partes específicas do processo ou da operação como um todo;
· Controle transacional integrado ao container (de forma automática em muitos casos).
A criação desta API tem como objetivo facilitar a construção e parametrização de processos em lote através da definição de um fluxo de etapas (steps). Estas etapas são descritas em um arquivo XML por meio de uma linguagem chamada JSL (Job Specification Language) de modo que cada processo em lote deve ser descrito em um arquivo XML separado. As etapas que compõem um processo podem ser implementadas de duas formas diferentes:
1. Processamento baseado em chunks: Esta opção é a mais flexível para o uso da API, no entanto, é explicitamente separada em três fases: 1) Leitura dos dados; 2) Processamento dos dados; e, 3) Escrita dos dados;
2. Processamento simples (Batchlet): Esta é uma opção mais simples, que delega para apenas uma classe a execução de toda a etapa.
A existência desses dois tipos de etapas (chunks e batchlets) permite que o desenvolvedor escolha a implementação mais adequada de acordo com a ação a ser executada. As características de cada etapa, como seu tipo, são indicadas no momento da definição da tarefa (job), realizada via JSL e melhor detalhada posteriormente no artigo.
As etapas baseadas em chunks são as que se beneficiam de mais recursos da API, porém são um pouco mais trabalhosas de serem implementadas. Uma das funcionalidades disponíveis para chunks é o particionamento da etapa para que seja executada em tarefas paralelas. Desta forma utilizamos melhor os diversos núcleos de processamento de um servidor, aproveitando melhor os recursos disponíveis e possivelmente acelerando a execução da etapa.
Ao particionarmos uma etapa do tipo chunk em tarefas paralelas a API também permite que estas tarefas sejam paradas, reiniciadas ou mesmo descartadas. Isto é possível porque a API possui uma estrutura de checkpoint que armazena o estado da execução das tarefas, guardando o estado da etapa para que esta possa ser reiniciada posteriormente, caso necessário.
Por todos estes conceitos estarem abstraídos pela API de processos batch, desenvolver aplicações que se beneficiem deste modelo de programação tornou-se mais fácil. Além disto, por estarmos em um container Java EE 7, ganhamos automaticamente a integração com outros recursos desta especificação, como acesso fácil ao banco de dados via JPA (Java Persistence API), injeção de dependências com CDI (Contexts and Dependendy Injection), agendadores de tarefas (Scheduler), etc.
Preparando o ambiente
Preparar um ambiente de desenvolvimento para se criar uma aplicação Java EE 7 é uma tarefa simples. Basta fazermos o download do JDK 7 e do GlassFish 4 versão full, servidor de aplicação de referência da especificação Java EE.
Além disto, para facilitar o desenvolvimento, iremos utilizar o Eclipse para a escrita de nosso código, o Maven como ferramenta de construção e controle de dependências do projeto, e o M2E, plugin do Eclipse que facilita a integração do Eclipse com o Maven.
Dentre as tecnologias empregadas para o nosso exemplo, iremos descrever apenas a instalação do GlassFish 4, visto que os outros já são amplamente adotados em grande parte dos projetos Java. Para mais detalhes sobre a instalação do Maven e do M2E, veja a seção Links.
Black November Desconto exclusivo para as primeiras 200 matrículas! Pagamento anual 12x no cartão De: R$ 69,00 Por: R$ 54,90 Total: R$ 658,80 Garanta o desconto Pagamento recorrente Cobrado mensalmente no cartão De: R$ 79,00 Por: R$ 54,90 /mês Total: R$ 658,80 Garanta o desconto Eu sabia pouquíssimas coisas de programação antes de começar a estudar com
vocês, fui me especializando em várias áreas e ferramentas que tinham na plataforma, e com essa
bagagem consegui um estágio logo no início do meu primeiro
período na faculdade. Estudo aqui na Dev desde o meio do ano passado!
Nesse período a Dev me ajudou a crescer muito aqui no trampo. Economizei 3 meses para assinar a plataforma e sendo sincero valeu muito a
pena, pois a plataforma é bem intuitiva e muuuuito
didática a metodologia de ensino. Sinto que estou EVOLUINDO a cada dia. Muito
obrigado! Nossa! Plataforma maravilhosa. To amando o curso de desenvolvimento
front-end, tinha coisas que eu ainda não tinha visto. A
didática é do jeito que qualquer pessoa consegue aprender. Sério, to apaixonado,
adorando demais. Adquiri o curso de vocês e logo percebi que são os melhores do Brasil. É
um passo a passo incrível. Só não aprende quem não quer.
Foi o melhor investimento da minha vida! Foi um dos melhores investimentos que já fiz na vida e tenho aprendido
bastante com a plataforma. Vocês estão fazendo parte da minha jornada nesse mundo da
programação, irei assinar meu contrato como programador
graças a plataforma.
Wanderson Oliveira
Comprei a assinatura tem uma semana,
aprendi mais do que 4 meses estudando outros cursos. Exercícios práticos que não tem
como não aprender, estão de parabéns! Obrigado DevMedia, nunca presenciei uma plataforma de ensino tão presente na vida acadêmica de
seus alunos, parabéns!
Eduardo Dorneles
Aprendi React na plataforma da DevMedia há cerca de 1 ano e meio... Hoje estou há 1 ano empregado trabalhando 100% com
React!
Adauto Junior
Já fiz alguns cursos na área e nenhum é tão bom quanto o de vocês. Estou aprendendo
muito, muito obrigado por existirem. Estão de parabéns... Espero um dia conseguir um emprego na
área. Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.Confira outros conteúdos:
<Perguntas frequentes>
Nossos casos de sucesso
Fui o primeiro desenvolvedor contratado pela minha
empresa. Hoje eu lidero um time de desenvolvimento!
Minha meta é continuar estudando e praticando para ser um
Full-Stack Dev!