Apex II - Async
Apex II - Async
Todas as operações vistas até o momento são operações em tempo real, síncronas. Nem
tudo é processamento em tempo real, podemos ter processamentos assíncronos, ou seja,
uma tarefa que pode ocorrer fora do tempo real, enquanto fazemos outras tarefas. Um
exemplo prático do dia a dia, quando fazemos download de algum arquivo muito grande na
casa dos Gigabytes, você fica parado na tela de download até que ele termine? Claro que
não, você vai fazer outras coisas no dispositivo.
Com a ideia de tarefas que podem ser executadas assincronamente, o Apex dá suporte a
várias formas de processamento assíncrono para o seu código. São eles:
● Métodos futuros
● Apex em Lote (Batch)
● Apex Agendado(Schedule)
● Apex em Fila (Queueable)
Os comandos, tarefas, são executados em segundo plano, fora da vista do usuário. São
executados quando os recursos dos servidores da Salesforce estiverem disponíveis.
Podemos criar códigos Apex agendados, onde eles rodarão em um tempo determinado,
podendo ser em questão de minutos, horas, dias, no fim do mês, vai depender da
necessidade.
Iremos conhecer um pouco sobre cada uma das formas de processamento assíncrono
disponíveis no Apex.
Métodos futuros
Métodos futuros são executados em segundo plano, de forma assíncrona. Você pode
invocar métodos futuros para executar operações de longa duração, para isolar DML de
diferentes sObjects com o intuito de prevenir erros.
Eles precisam ter anotação @future e precisam ser métodos estáticos que retornem apenas
o tipo void. Eles podem receber parâmetros de passagem, mas apenas aceitam tipos de
dados primitivos, listas e coleções de tipos de dados primitivos.
Eles não podem receber sObjects por conta de possíveis alterações que podem ocorrer
entre a hora que ele foi chamado e o seu tempo de execução. Para trabalhar com sObjects
podemos passar os ids de uma coleção e usá-los para uma consulta interna. Exemplo:
Um ponto importante sobre métodos futuros é que eles não podem invocar outros métodos
futuros dentro do seu interior, por exemplo, um método futuro A possuir dentro de seus
comandos, uma chamada de um método futuro B.
Vamos ao exemplo.
Vamos criar uma classe chamada AccountAsync e criar um método vazio para implementar.
Siga a estrutura de declaração do método futuro.
Vamos colocar uma consulta interna através dos valores recebidos de ids, como no
exemplo anterior. Com os valores vamos atualizar os campos colocando no campo industry
o valor other, em seguida, vamos atualizar.
Para executar nosso código assíncrono devemos abrir a guia anônima no console, criar
uma consulta básica de conta e depois repassar ao método futuro. Execute.
O que vemos aqui é a execução de processos em tempo real (aba anônima) e outro de
segundo plano (método futuro).
Log do Método Futuro.
Apex em Lote (Batch)
Também conhecido como Batch, podemos construir complexos e longos processamentos
de milhares de registros para a plataforma. Operando em pequenos lotes de registros,
cobrindo o conjunto de registros e dividindo o processamento em pedaços gerenciáveis.
É visto também como uma interface que deve ser implementada. As execuções do lote
podem ser implementadas. As execuções do lote podem ser feitas programadamente em
tempo de execução.
Uma classe batch é diferente de uma classe normal, pois possui uma interface que deve ser
implementada. A Database.Batchable.
Dentro desta classe temos três métodos implementados: start, execute e finish. Dentro de
cada classe Batch, sempre temos a definição desses métodos.
O método start é executado apenas uma vez, é nele que definimos o escopo dos registros.
Aqui coletamos os registros ou objetos para repassar os dados para o método ‘execute’.
Esse método retorna um objeto ‘queryLocator’ que é os registros capturados no start,
exemplo, a consulta retorna cerca de 26000 registros, esses registros serão passados para
o ‘queryLocator’ que irá fornecer os dados para o execute, com base no tamanho do lote.
Podemos processar até 50 milhões de registros.
O método execute é responsável por fazer o processamento do bloco de dados. O método
é chamado para cada lote de registro que você passa para ele, podendo ser chamado
inúmeras vezes. Esse método possui dois parâmetros: BatchableContext e uma Lista. O
BatchableContext é usado para rastrear o progresso de trabalho em lote e a lista recebe os
dados retornados pelo start. Para cada execução ele ganha um novo conjunto de limites de
governador.
E por último o método finish. É usado para enviar email de confirmação ou executar ações
de pós-processamento. Ele é chamado após processar todos os lotes.
Declaramos um objeto da classe de lote que criamos e logo após chamamos o método
executeBatch da classe Database. Esse método tem dois parâmetros a serem recebidos, a
instância do batch e o segundo que é opcional o tamanho do lote a ser processado. Esse
valor pode ser maior que zero e no máximo 2000. Quando o valor não é declarado por
padrão é 200.
Na palavra consulta dentro do método start iremos colocar uma consulta básica da SOQL
de Account.
No método execute vamos usar o comando de update que fizemos em método futuro só pra
executar uma ação.
E por último no finish apenas um debug confirmando o fim do processamento.
Feito isso nosso código Apex em lote está finalizado, vamos realizar um teste em aba
anônima e executar o mesmo. Vamos colocar um valor pequeno para o tamanho do lote,
valor 5, para vermos a execução de cada lote dentro do log.
Os processos do Apex que são executados por um longo tempo, como operações de banco
de dados extensas ou chamadas de serviço da web externas, podem ser executados de
forma assíncrona implementando a interface Queueable e adicionando um trabalho à fila de
trabalhos do Apex. Dessa forma, seu trabalho assíncrono do Apex é executado em segundo
plano em seu próprio encadeamento e não atrasa a execução de sua lógica principal do
Apex. Cada trabalho na fila é executado quando os recursos do sistema ficam disponíveis.
Um benefício de usar os métodos de interface Queueable é que alguns limites do
governador são mais altos do que para o Apex síncrono, como limites de tamanho de heap.
• Usando tipos não primitivos: sua classe que pode ser enfileirada pode conter variáveis
ember de tipos de dados não primitivos, como sObjects ou tipos personalizados do Apex.
Esses objetos podem ser acessados durante a execução do trabalho.