Trigger Record Creation funktioniert nicht in Bulk Update [Duplikat]
Wir haben einen Prozess, bei dem Datensätze, die mit Sync_Prospect_to_Pardot__c auf true aktualisiert werden, für jeden aktualisierten Datensatz einen pi__ObjectChangeLog__c-Datensatz erstellen sollten. Wenn ich jedoch den Datenlader zum Aktualisieren von 250 Datensätzen mit aktivierter Massen-API verwende, werden nur 200 pi__ObjectChangeLog__c-Datensätze erstellt. Wenn ich diese Einstellung deaktiviert habe, werden alle 250 erstellt. Ich habe ein Ticket mit Salesforce-Support angemeldet und sie sagten, es sei kein Problem mit dem Datenlader, und sie geben kein Feedback zum Code, da dieser außerhalb des Gültigkeitsbereichs liegt. Die Pardot-Unterstützung war nicht hilfreich, da wir einen benutzerdefinierten Prozess zum Erstellen der Objektänderungsprotokolle verwenden. Hier ist eindeutig etwas los und der Code unterscheidet sich nicht von dem, was ich für den Rest der Organisation geschrieben habe. Wir sehen keine Probleme bei der Verwendung von Bulk-API, um einen dieser Prozesse auszulösen.
Das pi__ObjectChangeLog__c-Objekt ist als "Massen-API-Zugriff zulassen" gekennzeichnet.
Ist das Problem der Code? Wenn nicht, welche anderen Dinge muss ich überprüfen? Ich erhalte die gleichen Ergebnisse, unabhängig davon, ob es sich bei dem Startobjekt um einen Kontakt oder einen Lead handelt.
Hier sind die Komponenten. Beachten Sie, dass wir das von Trailhead empfohlene SFDC Trigger Framework von Kevin O'Hara verwenden .
Auslösen
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();
}
Dispatcher
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);
}
}
}
Klasse
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');
}
}
Antworten
TriggerHandler.isBypassed wird im Triggercode referenziert, um zu überprüfen, ob es bereits ausgeführt wurde oder nicht.
Die Massen-API verarbeitet jedoch alle Datensätze unter einer Transaktion, was bedeutet, dass die statischen Variablen niemals zurückgesetzt werden.
Bitte beziehen Sie sich auf diese - Bulk-API und Static Variable State


Sie müssen den Bypass in Ihrem Dispatcher löschen, sobald die PardotSyncManager
Ausführung des Codes abgeschlossen ist.
Lassen Sie Ihren if-Block stattdessen effektiv so aussehen:
//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
}