Fermer

mars 13, 2024

Power Duo de Salesforce / Blogs / Perficient

Power Duo de Salesforce / Blogs / Perficient


Aloha les pionniers !

Dans le monde de Salesforce, l’exactitude des données est extrêmement importante. Mais parfois, surtout lorsqu’il s’agit de données volumineuses ou de processus complexes, cela peut devenir délicat. C’est là que les finaliseurs de transactions Apex s’avèrent utiles. Ce sont comme de petits assistants qui vous permettent d’effectuer des tâches supplémentaires une fois votre travail sur les données terminé. Vous aidant ainsi à garder les choses en ordre.

Quelle est la nécessité des finaliseurs Apex ?

Pour les développeurs familiers avec Async Apex, bien qu’il fournisse un ensemble d’outils puissants adaptés à différents scénarios, un défi persistant existe : la mise en œuvre d’une logique de nouvelle tentative pour les appels et la journalisation s’est avérée difficile. De plus, les administrateurs et les développeurs doivent savoir que la surveillance des transactions asynchrones peut être effectuée via l’onglet Tâches Apex de la page de configuration. Cependant, que se passe-t-il s’il est nécessaire d’avoir un contrôle plus granulaire sur ces transactions ?

Par exemple, les méthodes Future, de par leur conception, ne renvoient pas d’ID de tâche Apex. Bien que ces outils soient bénéfiques, que se passe-t-il s’il est nécessaire d’améliorer la logique de journalisation et de nouvelle tentative, dans le but de réduire la dépendance à Batch Apex ? C’est là qu’interviennent Queueable Apex et Finalizers. Avant les Transaction Finalizers, il était nécessaire de récupérer l’ID d’AsyncApexJob via SOQL et d’implémenter une logique de nouvelle tentative dans Queueable Apex. Il convient de noter que Batch Apex, avec ses limitations autorisant seulement cinq tâches exécutées simultanément par organisation, peut ne pas toujours suffire. Par conséquent, disposer d’améliorations apportées à Queueable Apex comme alternative est inestimable. Les files d’attente excellent dans la gestion du traitement Async Apex simple et dans l’envoi d’appels vers des systèmes externes avec de petits volumes de données. Cependant, avant les Finalizers, il était fastidieux de gérer des scénarios complexes impliquant des tâches en file d’attente enchaînées. Si une tâche de la chaîne échouait en raison d’exceptions limites ou pour d’autres raisons, la chaîne entière devait être réessayée.

Que font les finaliseurs Apex ?

Les finaliseurs de transactions vous permettent d’ajouter des actions à vos tâches Apex en file d’attente à l’aide d’une interface spéciale appelée Finalizer. Une fois l’exécution d’un travail utilisant Finalizer terminé, qu’il réussisse ou qu’il rencontre une erreur, le code Finalizer associé entre en jeu. Cela vous permet de faire des choses comme ranger ou récupérer de tout problème.

Avec les finaliseurs, vous pouvez effectuer de nombreuses tâches utiles. Par exemple, vous pouvez envoyer des notifications par e-mail pour rester informé de ce qui se passe. Vous pouvez également conserver des journaux détaillés à des fins de débogage et de surveillance. De plus, les finaliseurs vous permettent de réessayer automatiquement les tâches en file d’attente si elles rencontrent des erreurs. De plus, vous pouvez effectuer des appels externes vers d’autres systèmes une fois les opérations de base de données terminées, ce qui n’est généralement pas autorisé dans Apex.

Ceci est assez important, car effectuer un appel après avoir effectué des opérations de base de données n’est normalement pas autorisé dans Apex, mais les finaliseurs permettent de contourner cette limitation puisqu’ils s’exécutent une fois la tâche Queueable terminée. Les finaliseurs n’interviennent pas seulement en cas d’échec d’une tâche ; ils s’exécutent également lorsque le travail est terminé avec succès. Cela vous donne l’occasion idéale d’effectuer des tâches supplémentaires une fois la transaction terminée. Par exemple, vous pouvez enregistrer des informations importantes, effectuer des appels API supplémentaires ou effectuer toute autre tâche post-transaction que vous devez effectuer.

Exemple de nouvelle tentative en file d’attente

Cet exemple, que j’ai emprunté à la documentation Salesforce, montre comment remettre en file d’attente une tâche Queueable ayant échoué dans son finaliseur. Il souligne également que les tâches peuvent être réessayées jusqu’à cinq fois au maximum, en respectant la limite de chaînage en file d’attente.

public class RetryLimitDemo implements Finalizer, Queueable {
  public void execute(QueueableContext ctx) {
    String jobId = '' + ctx.getJobId();
    try {
        Finalizer finalizer = new RetryLimitDemo();
        System.attachFinalizer(finalizer);
        System.debug('Attached finalizer');
        Integer accountNumber = 1;
        while (true) { // results in limit error
          Account a = new Account();
          a.Name="Account-Number-" + accountNumber;
          insert a;
          accountNumber++;
        }
    } catch (Exception e) {
        System.debug('Error executing the job [' + jobId + ']: ' + e.getMessage());
    } finally {
        System.debug('Completed: execution of queueable job: ' + jobId);
    }
  }

  // Finalizer implementation
  public void execute(FinalizerContext ctx) {
    String parentJobId = '' + ctx.getAsyncApexJobId();
    System.debug('Begin: executing finalizer attached to queueable job: ' + parentJobId);
    if (ctx.getResult() == ParentJobResult.SUCCESS) {
        System.debug('Parent queueable job [' + parentJobId + '] completed successfully.');
    } else {
        System.debug('Parent queueable job [' + parentJobId + '] failed due to unhandled exception: ' + ctx.getException().getMessage());
        System.debug('Enqueueing another instance of the queueable...');
        String newJobId = '' + System.enqueueJob(new RetryLimitDemo()); // This call fails after 5 times when it hits the chaining limit
        System.debug('Enqueued new job: ' + newJobId);
    }
    System.debug('Completed: execution of finalizer attached to queueable job: ' + parentJobId);
  }
}

Contexte de file d’attente : Dans ce contexte, nous avons notre méthode standard execute(QueueableContext ctx) comme l’exige l’interface Queueable. Cette méthode sert de point d’entrée lorsque le travail est ajouté à la file d’attente.

Contexte du finaliseur : De plus, notre code inclut une méthode d’exécution (FinalizerContext ctx) mandatée par l’interface Finalizer. Cette méthode est déclenchée à la fin de la tâche Queueable, qu’elle réussisse ou qu’elle rencontre une erreur.

Il est important de noter que la classe queueable implémente l’interface Finalizer et qu’en utilisant System.attachFinalizer(finalizer);, nous connectons un Finalizer au travail Queueable actuel. Ce finaliseur est exécuté une fois la tâche Queueable terminée, quel que soit son résultat. Nous initialisons une nouvelle instance de finalizer en créant un nouvel objet : Finalizer finalizer = new RetryLimitDemo();.

Dans la méthode d’exécution du Queueable, si nous rencontrons une erreur de limite, nous mettons en file d’attente un nouveau Queueable en utilisant l’interface du finaliseur : String newJobId = System.enqueueJob(new RetryLimitDemo()). C’est aussi simple que ça !

Détails d’implémentation

  • Une seule instance de finaliseur peut être attachée à une tâche pouvant être mise en file d’attente.
  • Vous pouvez mettre en file d’attente une seule tâche Apex asynchrone (Queueable, Future ou Batch) dans l’implémentation de la méthode d’exécution par le finaliseur.
  • Les légendes sont autorisées dans les implémentations du finaliseur.
  • Le framework Finalizer utilise l’état de l’objet Finalizer (s’il est attaché) à la fin de l’exécution de Queueable. La mutation de l’état du Finalizer, une fois celui-ci attaché, est donc prise en charge.
  • Les variables déclarées transitoires sont ignorées par la sérialisation et la désérialisation et ne persistent donc pas dans Transaction Finalizer.

Conclusion

Dans Salesforce, les tâches en file d’attente et les finaliseurs fonctionnent dans des contextes Apex et base de données distincts. Cette configuration unique permet aux finaliseurs de s’exécuter même après avoir rencontré une erreur non détectée, car ils opèrent dans leur propre contexte d’exécution. Par conséquent, l’instance de classe Queueable d’origine qui a instancié le Finalizer n’existe plus. Par conséquent, il est préférable de s’abstenir de tenter de rappeler la classe Queueable à partir du Finalizer.

Je suis ravi de cette fonctionnalité et prévois son extension à d’autres aspects de la plate-forme, tels que les déclencheurs Apex. Actuellement, la capacité à gérer les erreurs Apex indétectables sans encourir de coûts supplémentaires pour la surveillance des événements est extrêmement précieuse. L’extension de cette fonctionnalité entraînerait une amélioration de la gestion des erreurs et de la gestion des bases de données. Alors que nous attendons avec impatience les améliorations potentielles, exprimons notre gratitude à l’équipe Apex pour son travail exceptionnel au cours des dernières années.

N’hésitez pas à explorer les liens de blog suivants pour plus d’informations :

Principes essentiels de JavaScript asynchrone pour Lightning Web Component (LWC)

Comment planifier une classe par lots Apex dans Salesforce ?

Finalisateurs Apex | Documentation Salesforce






Source link