ALL_OR_NONE_OPERATION_ROLLED_BACK oplossen in Salesforce-deployments

Eén slecht record in een batch die met allOrNone=true is verzonden, draaide elk record in die batch terug, inclusief de geldige.

Treedt op bij: bulk-DML-operaties, data loads en Apex-testsetup

Wat het betekent

ALL_OR_NONE_OPERATION_ROLLED_BACK betekent dat een DML-operatie is verzonden met allOrNone op true, en dat minstens één record in de batch de validatie niet doorstond, waardoor Salesforce de hele batch terugdraaide in plaats van de individueel geldige records vast te leggen. Dit is het verwachte gedrag van allOrNone, geen bug, maar het kan kostbaar zijn bij grote batches.

Het gebeurt overal waar bulk-DML draait: een Database.insert(records, true)-aanroep in Apex, een Bulk API-job met de allOrNone-jobinstelling ingeschakeld, of een Data Loader-sessie met "Insert null values" en gedeeltelijk slagen beide uitgeschakeld. Eén slechte rij ergens in de batch trekt de hele transactie mee onderuit.

Diagnose

Veelvoorkomende oorzaken

Eén record in een grote batch faalt de validatie
Een verkeerde picklistwaarde, een ontbrekend verplicht veld, of een mislukte validatieregel op één record maakt de hele allOrNone-batch ongeldig.
Gemengde recordtypen zijn niet vooraf gevalideerd
Een batch mengt records uit verschillende bronnen of vormen zonder elk record eerst te toetsen aan de validatieregels van het object.
Batches zijn niet opgesplitst in stukken
De datastap van een grote deployment verzendt één zeer grote batch in plaats van deze op te splitsen in kleinere, beter geïsoleerde stukken.

De oplossing

  1. Valideer records aan de clientzijde vóór verzending
    Controleer voor het verzenden van de batch de voor de hand liggende foutcondities, verplichte velden en picklistwaarden, aan de hand van de regels van het object.
  2. Stel allOrNone=false in tijdens migratierondes
    Voer migraties uit met allOrNone=false zodat individuele mislukkingen de rest van de batch niet blokkeren, en controleer en herstel daarna de mislukte records.
  3. Splits grote batches op in kleinere groepen
    Splits een grote data-operatie op in kleinere batches, zodat één slecht record slechts een klein deel van de totale lading beïnvloedt.
    List<SObject> chunk = new List<SObject>();
    for (Integer i = 0; i < records.size(); i++) {
        chunk.add(records[i]);
        if (chunk.size() == 200 || i == records.size() - 1) {
            Database.insert(chunk, false);
            chunk.clear();
        }
    }
In de praktijk

Hoe Serpent dit voorkomt

De dataoperaties van Serpent worden opgedeeld in stukken en gevalideerd als onderdeel van de pipeline, zodat één slecht record in een migratie vroeg opvalt tegen een kleine batch in plaats van een grote batch diep in een deployment terug te draaien. Zie de bibliotheek met Salesforce-deploymentfouten.

Releasedashboard met conflictmeldingen in Serpent

Preventie

Gebruik standaard allOrNone=false voor bulklading
Behandel allOrNone=true als uitzondering voor gevallen waarin gedeeltelijk slagen echt onacceptabel is, niet als standaard voor elke batchjob.
Valideer vooraf, vóór verzending
Laat binnenkomende records door een lichte schemacontrole lopen, verplichte velden, picklistwaarden, voordat ze ooit de DML-aanroep bereiken.
Ontwerp migraties vanaf dag één met vaste chunkgroottes
Bouw data loads zodat ze vanaf het begin in vaste chunkgroottes worden verzonden, 200 tot 2.000 records, in plaats van chunking pas achteraf toe te voegen na een mislukking.
Veelgestelde vragen

ALL_OR_NONE_OPERATION_ROLLED_BACK, uitgelegd

Is allOrNone altijd de verkeerde instelling?
Nee. Het is de juiste keuze wanneer gedeeltelijk slagen onacceptabel is, zoals een set financiële records die samen geboekt moeten worden; het is alleen kostbaar bij grote, losjes gevalideerde batches.
Draait allOrNone=true ook neveneffecten van Apex-triggers terug?
Ja. Salesforce draait de hele transactie terug, inclusief elke DML die een trigger op andere objecten heeft uitgevoerd, niet alleen de rechtstreeks verzonden records.
Hoe vind ik welk specifiek record in een grote batch mislukte?
De SaveResult-array (of het Bulk API-jobresultaat) bevat één item per verzonden record, elk met een eigen successtatus en foutenlijst; loop erdoorheen om de mislukking te isoleren.

Start gratis. Geen creditcard, geen installatie, geen verplichting.

Binnen 15 minuten ingericht. Geen DevOps-aanwerving nodig.

Benieuwd naar sneller releasen voordat je instapt? Laten we praten

Vrijblijvend.