Programar trabajos con el programador de Apex
Objetivos de aprendizaje
Siga el proceso con Trail Together
¿Desea seguir el proceso con un instructor a medida que realiza este paso? Eche un vistazo a este video, parte de la serie Trail Together en Trailhead Live.
(Este video comienza en el minuto 01:09:53 a.m., en caso de que desee rebobinar y mirar el comienzo del paso nuevamente).
Apex programado
El programador de Apex permite retrasar la ejecución para que pueda ejecutar clases de Apex en un momento especificado. Esta opción es ideal para tareas de mantenimiento diarias o semanales mediante Apex por lotes. Para aprovechar las ventajas del programador, escriba una clase de Apex que implemente la interfaz Schedulable
y, a continuación, prográmela para la ejecución según una programación específica.
Sintaxis de Apex programado
Para invocar clases de Apex para su ejecución en momentos específicos, primero debe implementar la interfaz Schedulable
para la clase correspondiente. A continuación, programe una instancia de la clase para su ejecución en un momento específico mediante el método System.schedule()
.
public class SomeClass implements Schedulable { public void execute(SchedulableContext ctx) { // awesome code here } }
La clase implementa la interfaz Schedulable
y debe implementar el único método que contiene esta interfaz, que en este caso es el método execute()
.
El parámetro de este método es un objeto SchedulableContext
. Una vez que se ha programado una clase, se crea un objeto CronTrigger
que representa el trabajo programado. En este caso, se proporciona un método getTriggerId()
que devuelve el Id. de un objeto de API CronTrigger
.
Código de ejemplo
Esta clase consulta las oportunidades abiertas que deberían estar cerradas en la fecha actual y crea una tarea en cada caso para recordar al propietario que actualice la oportunidad.
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); } }
Puede programar la clase para que se ejecute mediante programación o bien en la interfaz de usuario del programador de Apex.
Uso del método System.Schedule
Después de implementar una clase con la interfaz Schedulable
, use el método System.Schedule()
para ejecutarla. El método System.Schedule()
usa la zona horaria del usuario como la base de todas las programaciones, pero se ejecuta en el modo del sistema. Es decir, se ejecutan todas las clases con independencia de que el usuario tenga o no permiso para ejecutar las clases.
El método System.Schedule()
usa tres argumentos: un nombre para el trabajo, una expresión CRON para representar la hora y la fecha de la ejecución programada del trabajo, y una instancia de una clase que implemente la interfaz Schedulable
.
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 obtener más información sobre el uso de la expresión CRON para la programación consulte la sección sobre el uso del método System.Schedule en Apex Scheduler.
Programación de un trabajo en la interfaz de usuario
- Desde Configuración, ingrese
Apex
en el cuadro Búsqueda rápida y, a continuación, seleccione Clases de Apex. - Haga clic en Programar Apex.
- Para el nombre del trabajo, ingrese algo parecido a
Daily Oppty Reminder.
- Haga clic en el botón de búsqueda junto a la clase de Apex e ingrese
*
como término de búsqueda para obtener una lista de todas las clases que se pueden programar. En los resultados de la búsqueda, haga clic en el nombre de la clase programada. - Seleccione
Semanal
oMensual
para establecer la frecuencia que desee. - Seleccione las fechas de inicio y finalización, y una hora de inicio preferida.
- Haga clic en Guardar.
Prueba de Apex programado
Al igual que ocurre con otros métodos asíncronos que hemos descrito, en el caso de Apex programado también debe asegurarse de que el trabajo programado haya finalizado antes de realizar pruebas con los resultados. Para ello, use startTest()
y stopTest()
de nuevo con el método System.schedule()
para asegurarse de que el proceso ha finalizado antes de realizar las pruebas.
@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'); } }
Aspectos que recordar
- Solo puede tener 100 trabajos de Apex programados a la vez y hay un número máximo de ejecuciones de Apex programadas durante cada periodo de 24 horas. Consulte los límites de ejecución y reguladores en la sección Recursos para obtener información detallada.
- Extreme la precaución si su plan es programar una clase desde un desencadenador. Debe poder garantizar que el desencadenador no agregará un número de trabajos programados superior al límite.
- Las llamadas de servicio web no son compatibles con Apex programado. Para poder hacer llamadas, realice una llamada asíncrona mediante la inclusión de la llamada en un método anotado con
@future(callout=true)
y llame a este método desde Apex programado. Sin embargo, si Apex programado ejecuta un trabajo por lotes, las llamadas son compatibles con la clase por lotes.