Agendar trabalhos com o Agendador do Apex

Objetivos de aprendizagem

Após concluir esta unidade, você saberá:
  • Quando usar o Apex agendado.
  • Como monitorizar trabalhos agendados.
  • Sintaxe do Apex agendado.
  • Melhores práticas para o método agendado.

Apex agendado

O Agendador do Apex permite atrasar a execução para que você possa executar as classes do Apex em uma hora especificada. Isso é ideal para tarefas de manutenção diária ou semanal com o Apex de lote. Para aproveitar o agendador, escreva uma classe do Apex que implemente a interface Schedulable e agende-a para execução em uma agenda específica.

Sintaxe do Apex agendado

Para invocar classes do Apex para serem executadas em horários específicos, implemente antes a interface Schedulable para a classe. Depois, agende uma instância da classe para ser executada em um momento específico usando o método System.schedule.

global class SomeClass implements Schedulable {
    global void execute(SchedulableContext ctx) {
        // awesome code here
    }
}

Esta classe implementa a interface Schedulable e deve implementar o único método que essa interface contém, que é o método execute.

O parâmetro desse método é um objeto SchedulableContext. Após a classe ter sido agendada, um objeto CronTrigger é criado para representar o trabalho agendado. Isso oferece um método getTriggerId que retorna o ID de um objeto API CronTrigger.

Código de exemplo

Esta classe consulta oportunidades abertas que deveriam ter sido fechadas até a data atual e cria uma tarefa em cada uma para lembrar o proprietário de atualizar a oportunidade.

global class RemindOpptyOwners implements Schedulable {
    global void execute(SchedulableContext ctx) {
        List<Opportunity> opptys = [SELECT Id, Name, OwnerId, CloseDate
            FROM Opportunity
            WHERE IsClosed = False AND
            CloseDate < TODAY];
        // Create a task for each opportunity in the list
        TaskUtils.remindOwners(opptys);
    }
}

É possível programar sua classe para ser executada por programação ou a partir da IU do Agendador do Apex.

Como usar o método System.Schedule

Após implementar uma classe com a interface Schedulable, use o método System.Schedule para executá-la. O método System.Schedule usa o fuso horário do usuário para a base de todos os agendamentos, mas é executado em modo de sistema: todas as classes são executadas, independente de o usuário ter ou não permissão para executar a classe.

Nota

Nota

Tome muito cuidado se estiver planejando programar uma classe a partir de um acionador. Você tem de garantir que o acionador não adicionará mais classes de trabalhos agendados do que o limite. Considere, em especial, atualizações em lote de API, assistentes de importação, alterações de registros em massa por meio da interface de usuário e todos os casos nos quais mais de um registro pode ser atualizado por vez.

O método System.Schedule considera três argumentos: um nome para o trabalho, uma expressão CRON usada para representar a data e hora na qual o trabalho está agendado para ser executado e o nome da classe.

RemindOpptyOwners reminder = new RemindOpptyOwners();
// Seconds Minutes Hours Day_of_month Month Day_of_week optional_year
String sch = '20 30 8 10 2 ?';
String jobID = System.schedule('Remind Opp Owners', sch, reminder);

Para mais informações sobre a expressão CRON usada para o agendamento, consulte a seção “Como usar o método System.Schedule” no Agendador do Apex.

Como programar um trabalho a partir da IU

Também é permitido agendar uma classe usando a interface de usuário.
  1. Em Configuração, insira Apex na caixa Busca rápida e selecione Classes do Apex.
  2. Clique em Agendar Apex.
  3. Para o nome do trabalho, digite algo como Daily Oppty Reminder.
  4. Clique no botão de pesquisa junto à classe do Apex e digite * como termo para pesquisa para obter uma lista de todas as classes que podem ser agendadas. Nos resultados da pesquisa, clique no nome de sua classe agendada.
  5. Selecione a frequência Semanal ou Mensal para definir a frequência desejada.
  6. Selecione as datas inicial e final e a hora de início desejada.
  7. Clique em Salvar.

Como testar o Apex agendado

Assim como os outros métodos assíncronos abordados até agora, com o Apex agendado é necessário garantir que o trabalho agendado seja finalizado antes de verificar os resultados. Para isso, use novamente o startTest e o stopTest no método System.schedule para ter certeza de que o processo foi finalizado antes de continuar seu teste.

@isTest
private class RemindOppyOwnersTest {
    // Dummy CRON expression: midnight on March 15.
    // Because this is a test, job executes
    // immediately after Test.stopTest().
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';
    static testmethod void testScheduledJob() {
        // Create some out of date Opportunity records
        List<Opportunity> opptys = new List<Opportunity>();
        Date closeDate = Date.today().addDays(-7);
        for (Integer i=0; i<10; i++) {
            Opportunity o = new Opportunity(
                Name = 'Opportunity ' + i,
                CloseDate = closeDate,
                StageName = 'Prospecting'
            );
            opptys.add(o);
        }
        insert opptys;
        // Get the IDs of the opportunities we just inserted
        Map<Id, Opportunity> opptyMap = new Map<Id, Opportunity>(opptys);
        List<Id> opptyIds = new List<Id>(opptyMap.keySet());
        Test.startTest();
        // Schedule the test job
        String jobId = System.schedule('ScheduledApexTest',
            CRON_EXP,
            new RemindOpptyOwners());
        // Verify the scheduled job has not run yet.
        List<Task> lt = [SELECT Id
            FROM Task
            WHERE WhatId IN :opptyIds];
        System.assertEquals(0, lt.size(), 'Tasks exist before job has run');
        // Stopping the test will run the job synchronously
        Test.stopTest();
        // Now that the scheduled job has executed,
        // check that our tasks were created
        lt = [SELECT Id
            FROM Task
            WHERE WhatId IN :opptyIds];
        System.assertEquals(opptyIds.size(),
            lt.size(),
            'Tasks were not created');
    }
}

Coisas a serem lembradas

O Apex agendado tem alguns itens aos quais você deve estar atento (quando tiver tempo, consulte Agendador do Apex, na seção Recursos, para obter uma lista completa), mas em geral:
  • Só podem ser agendados 100 trabalhos do Apex por vez e há um número máximo de execuções Apex agendadas para um período de 24 horas. Consulte Administradores e limites de execução, na seção Recursos, para obter detalhes.
  • Tome muito cuidado se estiver planejando programar uma classe a partir de um acionador. Você tem de garantir que o acionador não adicionará mais trabalhos agendados do que o limite.
  • Os callouts de serviço da Web síncronos não são aceitos a partir do Apex agendado. Para poder fazer callouts, faça um callout assíncrono colocando-o em um método anotado com @future(callout=true) e chame este método no Apex agendado. Porém, se seu Apex agendado executar um trabalho em lote, os callouts são compatíveis com a classe de lote.

Recursos

Nota

Nota

Lembre-se: este módulo é destinado ao Salesforce Classic. Quando você iniciar sua organização prática, mude para o Salesforce Classic para concluir este desafio.

Continue a aprender de graça!
Inscreva-se em uma conta para continuar.
O que você ganha com isso?
  • Receba recomendações personalizadas para suas metas de carreira
  • Pratique suas habilidades com desafios práticos e testes
  • Monitore e compartilhe seu progresso com os empregadores
  • Conecte-se a orientação e oportunidades de carreira