La création d’enregistrements de déclenchement ne fonctionne pas dans la mise à jour groupée [duplicate]
Nous avons un processus où lorsque les enregistrements sont mis à jour avec Sync_Prospect_to_Pardot__c à true, il doit créer un enregistrement pi__ObjectChangeLog__c pour chaque enregistrement mis à jour. Cependant, lorsque j'utilise le chargeur de données pour mettre à jour 250 enregistrements avec l'API Bulk activée, seuls 200 enregistrements pi__ObjectChangeLog__c sont créés. Si je n'ai pas coché ce paramètre, tous les 250 créent. J'ai enregistré un ticket avec l'assistance Salesforce et ils ont dit que ce n'était pas un problème avec le chargeur de données et qu'ils ne fourniraient pas de commentaires sur le code car il est hors de portée. La prise en charge de Pardot n'a pas été utile car nous utilisons un processus personnalisé pour créer les journaux de modification d'objet. Il se passe clairement quelque chose ici et le code n'est rien de différent de ce que j'ai écrit pour le reste de l'organisation. Nous ne voyons aucun problème d'utilisation de l'API en bloc pour déclencher l'un de ces processus.
L'objet pi__ObjectChangeLog__c est marqué comme "Autoriser l'accès à l'API en masse".
Le problème est-il le code? Sinon, quelles autres choses dois-je vérifier? J'obtiens les mêmes résultats que le sobject de départ soit un contact ou un prospect.
Voici les composants. Notez que nous utilisons le SFDC Trigger Framework de Kevin O'Hara comme recommandé par Trailhead .
Déclencheur
trigger LeadTrigger on Lead (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
Map<String, Trigger_Settings__c> triggerSettings = Trigger_Settings__c.getAll();
if(triggerSettings.get('LeadTrigger') <> null && triggerSettings.get('LeadTrigger').Execute_Trigger__c)
new LeadTriggerDispatcher().run();
}
Répartiteur
public without sharing class LeadTriggerDispatcher extends TriggerHandler {
//Trigger context variables are still available but need to be cast: trigger.new, trigger.newMap, trigger.oldMap
List<Lead> leads = (List<Lead>) trigger.new;
Map<Id, Lead> leadsOldMap = (Map<Id, Lead>) trigger.oldMap;
Map<Id, Lead> leadsNewMap = (Map<Id, Lead>) trigger.newMap;
Map<String, Trigger_Settings__c> triggerSettings = Trigger_Settings__c.getAll();
protected override void afterUpdate() {
//declare variables
Set<sObject> leadsForSync = new Set<sObject>();
//loop through to find qualifying records
for(Lead lead : leads) {
//leads are eligible for sync if their sync to prospect field changes, but no email changes were made. By default an OCL gets created if the email is updated
if(leadsOldMap.get(lead.Id).Sync_Prospect_to_Pardot__c == false && leadsNewMap.get(lead.Id).Sync_Prospect_to_Pardot__c == true)
leadsForSync.add((sObject)lead);
}
//execute methods
if(!leadsForSync.isEmpty() && !TriggerHandler.isBypassed('PardotSyncManager') && triggerSettings.get('PardotSyncManager') <> null && triggerSettings.get('PardotSyncManager').Execute_Trigger__c) {
TriggerHandler.bypass('PardotSyncManager');
PardotSyncManager.createObjectChangeLog(leadsForSync);
}
}
}
Classe
public without sharing class PardotSyncManager {
//createObjectChangeLog takes a set of lead or contact records and creates an OCL record for those records. Called from the contact or lead dispatcher
public static void createObjectChangeLog(Set<sObject> records) {
system.debug('PardotSyncManager Start');
system.debug('records size: ' + records.size());
//oclsForInsert stores a list of OCLs that need to be inserted
List<pi__ObjectChangeLog__c> oclsForInsert = new List<pi__ObjectChangeLog__c>();
//Iterate through all records in the scope
for(sObject record : records) {
system.debug('record Ids: ' + record.Id);
//Check if the record is a contact. If so, then parse the sObject to a contact and then create an OCL for that contact.
if(String.valueOf(record.Id).substring(0,3) == '003') {
Contact contact = (Contact)record;
oclsForInsert.add(new pi__ObjectChangeLog__c(pi__ObjectEmail__c = contact.Email, pi__ObjectFid__c = contact.Id, pi__ObjectType__c = 1, pi__ObjectState__c = 1));
}
//Check if the record is a lead. If so, then parse the record into a lead and then create an OCL for that lead.
else if(String.valueOf(record.Id).substring(0,3) == '00Q') {
system.debug('lead qualified');
Lead lead = (Lead)record;
oclsForInsert.add(new pi__ObjectChangeLog__c(pi__ObjectEmail__c = lead.Email, pi__ObjectFid__c = lead.Id, pi__ObjectType__c = 2, pi__ObjectState__c = 1));
}
}
//try to insert the OCL records
try {
system.debug('ocls for insert: ' + oclsForInsert.size());
insert oclsForInsert;
}
//If there's an error, post the error to the debug log
catch(Exception e) {
system.debug('EXCEPTION in PardotSyncManager.createObjectChangeLog at row ' + e.getLineNumber() + ': ' + e.getMessage());
}
system.debug('PardotSyncManager Complete');
}
}
Réponses
TriggerHandler.isBypassed est référencé dans le code de déclenchement pour vérifier s'il est déjà exécuté ou non.
Mais l'API Bulk traite tous les enregistrements sous une seule transaction, ce qui signifie que les variables statiques ne sont jamais réinitialisées.
Veuillez vous référer à ceux-ci - API en masse et état de variable statique


Vous devez effacer le contournement dans votre répartiteur une fois que le PardotSyncManager
code est terminé.
Pour que votre bloc if ressemble à ceci à la place:
//execute methods
if (
!leadsForSync.isEmpty() &&
!TriggerHandler.isBypassed('PardotSyncManager') && // this is causing it to only run on the first iteration
triggerSettings.get('PardotSyncManager') <> null &&
triggerSettings.get('PardotSyncManager').Execute_Trigger__c
) {
// turn off the trigger handler
TriggerHandler.bypass('PardotSyncManager');
// do the work
PardotSyncManager.createObjectChangeLog(leadsForSync);
// turn the trigger handler back on
TriggerHandler.clearBypass('PardotSyncManager'); // because this bypass removal was not here
}