So beheben Sie UNABLE_TO_LOCK_ROW in Salesforce-Deployments

Ein Datensatz, den das Deployment aktualisieren muss, ist durch eine andere gleichzeitig laufende Transaktion gesperrt.

Tritt auf bei: Laufzeit-DML, eine Timing-Kollision statt eines Metadaten- oder Datenproblems

Was das bedeutet

UNABLE_TO_LOCK_ROW bedeutet, dass Salesforce keine Sperre für einen Datensatz erlangen konnte, weil eine andere Transaktion, ein Batch-Job, ein geplanter Flow oder ein gleichzeitiger Apex-Test, ihn bereits aktualisierte. Dies ist ein Timing-Problem, kein Metadatenproblem: Das Deployment oder seine Tests sind korrekt, kollidierten aber mit etwas anderem, das in der Org lief.

Es ist besonders häufig bei Master-Detail-Beziehungen, da die Aktualisierung eines beliebigen Child-Datensatzes eine Sperre auf den Parent für die Neuberechnung der Roll-up-Summary erlangt, sodass zwei Child-Inserts, die gleichzeitig denselben Parent aktualisieren wollen, um diese Sperre konkurrieren.

Diagnose

Häufige Ursachen

Deployment während aktiver Org-Nutzung
Ein anderer Benutzer oder geplanter Prozess aktualisiert dieselben Parent-Datensätze, während die Apex-Tests des Deployments laufen.
Tests aktualisieren einen gemeinsamen Singleton-Datensatz
Mehrere Testklassen aktualisieren parallel denselben org-weiten Konfigurations- oder Einstellungsdatensatz.
Master-Detail-Rollups konkurrieren um den Parent
Mehrere Child-Inserts lösen gleichzeitig Neuberechnungen der Roll-up-Summary am selben Master-Datensatz aus.

Die Lösung

  1. Deployment erneut versuchen
    Zeilensperren sind vorübergehend. Ein erneuter Lauf desselben Deployments gelingt oft, sobald die konkurrierende Transaktion abgeschlossen ist.
  2. Während eines Zeitfensters mit geringer Aktivität deployen
    Planen Sie Produktions-Deployments außerhalb der Geschäftszeiten oder pausieren Sie zunächst kollidierende geplante Jobs.
  3. Konkurrenz um gemeinsame Datensätze in Tests vermeiden
    Strukturieren Sie Apex-Tests so um, dass nicht alle innerhalb derselben Transaktion denselben Singleton-Einstellungsdatensatz aktualisieren.
    for (Account parent : [SELECT Id FROM Account WHERE Id IN :parentIds FOR UPDATE]) {
        // lock parents explicitly and predictably before child DML
    }
In der Praxis

Wie Serpent das verhindert

Serpent AI plant Deployments so, dass bekannte kollidierende Jobs vermieden werden, und eine gesperrte Zeile erscheint als Ein-Klick-Wiederholung derselben Aufgabe statt als fehlgeschlagener Release. Siehe die Bibliothek der Salesforce-Deployment-Fehler.

Release-Dashboard mit Konfliktwarnungen in Serpent

Prävention

Bulk-Jobs und geplanten Flows nicht überlappende Zeitfenster geben
Staffeln Sie geplante Batch-Jobs, Datenladevorgänge und Deployments, damit sie nicht gleichzeitig um dieselben Parent-Datensätze konkurrieren.
Gemeinsame Singleton-Einstellungsdatensätze für geringe Konkurrenz gestalten
Vermeiden Sie, dass viele unabhängige Testklassen oder Trigger alle in einen einzigen org-weiten Einstellungsdatensatz schreiben; teilen Sie die Konfiguration nach Bereich auf, wo möglich.
Automatische Wiederholung für diesen speziellen Fehler ins Deployment-Tooling einbauen
Konfigurieren Sie die CI so, dass sie UNABLE_TO_LOCK_ROW gezielt erkennt und automatisch ein- oder zweimal wiederholt, da dies einer der wenigen Salesforce-Fehler ist, bei denen eine bloße Wiederholung die richtige Lösung ist.
Häufige Fragen

UNABLE_TO_LOCK_ROW, erklärt

Wird UNABLE_TO_LOCK_ROW jemals durch fehlerhafte Metadaten verursacht?
Selten. Es ist fast immer eine Timing-Kollision mit einem anderen Prozess, weshalb ein einfacher erneuter Versuch des Deployments die meisten Fälle löst.
Verhindert die Verwendung von FOR UPDATE in SOQL diesen Fehler oder verursacht sie ihn?
FOR UPDATE erlangt absichtlich eine Sperre, kann also UNABLE_TO_LOCK_ROW auslösen, wenn eine andere Transaktion die Sperre bereits hält; korrekt eingesetzt macht es die Sperrung explizit und vorhersehbar statt zufällig.
Wie oft sollte eine Pipeline es erneut versuchen, bevor dies als echter Fehler behandelt wird?
Zwei oder drei Wiederholungen mit kurzer Verzögerung dazwischen fangen die überwiegende Mehrheit vorübergehender Sperrkollisionen ab; schlägt es danach immer noch fehl, behandeln Sie es als echtes, untersuchungswürdiges Designproblem.

Kostenlos starten. Keine Kreditkarte, keine Installation, keine Verpflichtung.

In unter 15 Minuten eingerichtet. Keine DevOps-Einstellung nötig.

Neugierig auf schnelleres Shipping, bevor Sie einsteigen? Sprechen wir

Unverbindlich.