Skip to main content
Junte-se a nós na TDX em São Francisco ou no Salesforce+ nos dias 5 e 6 de maio e assista à Developer Conference for the AI Agent Era. Registre-se agora.

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.
Nota

Nota

Deseja aprender em português (Brasil)? Comece o desafio em um Trailhead Playground de português (Brasil) e copie e cole os valores de português (Brasil). Se você não passar no desafio em sua organização de português (Brasil), recomendamos que (1) mude o local para os Estados Unidos, (2) mude o idioma para inglês, seguindo as instruções aqui, e (3) clique novamente no botão “Validar o desafio”.

Consulte o emblema Trailhead no seu idioma para saber mais sobre como aproveitar a experiência de Trailhead em outros idiomas.

Acompanhar com o Trail Together

Deseja acompanhar um instrutor enquanto trabalha nesta etapa? Veja este vídeo que faz parte da série Trail Together no Trailhead Live.

(Este clipe começa na marca dos 01:09:53 minutos, caso você queira retroceder e ver o início da etapa novamente.)

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 Passível de agendamento 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().

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

Esta classe implementa a interface Schedulable (Passível de agendamento) e deve implementar o único método que esta interface contém, que é o método execute().

O parâmetro deste 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 a 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.

public class RemindOpptyOwners implements Schedulable {
    public 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 (Passível de agendamento), 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

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() utiliza 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 uma instância de uma classe que implemente a interface Schedulable (Passível de agendamento).

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 Lembretes diários da oportunidade.
  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 garantir que o processo seja 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 ? 2042';
    @IsTest
    static 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 a partir do Apex agendado. Porém, se seu Apex agendado executar um trabalho em lote, os callouts são compatíveis com a classe de lote.

Desafio prático

+500 pontos

Prepare-se

Você concluirá este(a) unidade em sua própria organização prática. Clique em Iniciar para começar, ou clique no nome da sua organização para escolher uma diferente.

Seu desafio

Criar uma classe do Apex que usa Apex agendado para atualizar registros de lead.
Crie uma classe do Apex que implementa a interface Schedulable para atualizar registros de lead com um LeadSource específico. (Isso é muito semelhante ao que você fez em Batch Apex.)
  • Crie uma classe do Apex:
    • Nome: DailyLeadProcessor
    • Interface: Schedulable
    • O método execute precisa encontrar os primeiros 200 registros Lead com um campo LeadSource e atualizá-los com o valor LeadSource de Dreamforce
  • Crie uma classe de teste do Apex:
    • Nome: DailyLeadProcessorTest
    • Na classe de teste, insira 200 registros Lead, agende a execução da classe DailyLeadProcessor e teste se todos os registros Lead foram atualizados corretamente
    • Os testes de unidade precisam cobrir todas as linhas de código incluídas na classe DailyLeadProcessor, resultando em 100% de cobertura de código.
  • Antes de verificar este desafio, execute sua classe de teste pelo menos uma vez usando o recurso do Developer Console Run All
Compartilhe seu feedback do Trailhead usando a Ajuda do Salesforce.

Queremos saber sobre sua experiência com o Trailhead. Agora você pode acessar o novo formulário de feedback, a qualquer momento, no site Ajuda do Salesforce.

Saiba mais Continue compartilhando feedback