Zum Inhalt springen
DedicatedPHP Kontakt

Transaktionen für Stapelverarbeitung bei PHP-Importen entwerfen

Erfahre, wie du Transaktionsgrenzen festlegst, Checkpoints speicherst und PHP-Importe fortsetzt, ohne Änderungen zu duplizieren oder Teilfehler zu verschleiern.

Redaktionelle Darstellung eines PHP-Imports in Stapeln mit Transaktionen, Checkpoints und Fehlerwiederherstellung

Ein umfangreicher Import kann durch eine unterbrochene Verbindung, ungültige Daten oder ein Zeitlimit des Prozesses scheitern. Wenn alle Änderungen von einer einzigen Transaktion abhängen, kann das System zu lange Sperren halten und die gesamte bis dahin geleistete Arbeit verlieren, die erst am Ende bestätigt würde. Wird dagegen jede Zeile einzeln und ohne Wiederherstellungsplan gespeichert, kann eine Unterbrechung inkonsistente Daten hinterlassen.

Transaktionen für Stapelverarbeitung bei PHP-Importen zu entwerfen bedeutet, Arbeitseinheiten auszuwählen, die sicher bestätigt, protokolliert und wiederholt werden können. Das ist nicht gleichbedeutend damit, den gesamten Import atomar zu machen: Üblicherweise ist jeder Stapel für sich atomar, während der gesamte Prozess teilweise angewendet sein kann. Diese Unterscheidung muss sich sowohl in der Implementierung als auch im betrieblichen Umgang widerspiegeln.

Warum eine einzige Transaktion ungeeignet sein kann

Warum eine einzige Transaktion ungeeignet sein kann — guía visual de DedicatedPHP

Eine lange Transaktion kann Sperren halten, die Belastung des Transaktionslogs erhöhen und mit Abfragen der Anwendung konkurrieren. Verarbeitet der Import Millionen von Zeilen, ist außerdem schwer festzustellen, wie viel noch fehlt und was nach einem Fehler zu tun ist. Das genaue Verhalten hängt von der Datenbank-Engine, der Isolationsstufe und dem Schreibvolumen ab. Deshalb sollte es in der tatsächlichen Umgebung gemessen werden.

Jede Zeile einzeln zu bestätigen verkürzt zwar die Dauer der einzelnen Transaktionen, kann aber die Kosten für Bestätigungen vervielfachen und Abhängigkeiten zwischen Zeilen nur teilweise anwenden. Der Stapel bildet einen Mittelweg: Schlägt ein Vorgang innerhalb der Gruppe fehl und wird die Ausnahme weitergegeben, wird diese Gruppe zurückgerollt; bereits bestätigte vorherige Stapel bleiben erhalten. Die Anwendung sollte dies als teilweisen Fortschritt kommunizieren, nicht als Gesamterfolg oder vollständigen Rollback.

Die passende Transaktionsgrenze wählen

Die Arbeitseinheit muss nicht immer aus einer festen Anzahl von Zeilen bestehen. Sie sollte Änderungen umfassen, die sich konsistent validieren und dauerhaft speichern lassen. Sind die einzelnen Datensätze unabhängig, kann ein Stapel von Zeilen ausreichen. Bilden mehrere Datensätze eine Geschäftsentität – zum Beispiel ein Kopfdatensatz und seine Positionen –, verhindert ihre Speicherung in derselben Transaktion, dass eine unvollständige Entität gespeichert wird.

Um die Stapelgröße festzulegen, solltest du die Dauer der einzelnen Stapel, den Speicherbedarf, die Konkurrenz um gemeinsam genutzte Tabellen, die Fehlerhäufigkeit und die Kosten einer Wiederholung bewerten. Ein großer Stapel verringert die Anzahl der Bestätigungen, benötigt aber mehr Verarbeitungszeit und vergrößert den Arbeitsumfang, der bei einem Fehler wiederholt werden muss. Ein kleiner Stapel begrenzt diesen Aufwand, erhöht jedoch den Overhead und kann die Leistung beeinträchtigen. Eine universell passende Größe gibt es nicht: Beginne mit einem konfigurierbaren Wert und passe ihn anhand repräsentativer Lasttests an.

Vermeide es in PHP, die gesamte Datei im Speicher anzusammeln, wenn sie schrittweise verarbeitet werden kann. Lies eine begrenzte Gruppe von Zeilen ein, validiere ihre Felder, beginne die Transaktion, führe die Schreibvorgänge aus und bestätige sie. Tritt ein Fehler auf, rolle die Transaktion des Stapels zurück und klassifiziere den Fehler. Mit PDO lässt sich die Steuerung beispielsweise durch beginTransaction(), commit() und rollBack() ausdrücken; die Ausnahmebehandlung muss sicherstellen, dass nicht versucht wird, eine fehlgeschlagene Transaktion zu bestätigen.

Fortschritt für eine zuverlässige Wiederaufnahme speichern

Ein Checkpoint gibt an, welcher Teil der Quelle bereits bestätigt verarbeitet wurde. Dabei kann es sich um eine stabile ID, eine Position in einer Datei oder einen zusammengesetzten Schlüssel handeln – vorausgesetzt, die Verarbeitung kann fortgesetzt werden, ohne von einer veränderlichen Reihenfolge abzuhängen. Bei einer paginierten Abfrage ist es oft sicherer, anhand eines stabilen Schlüssels weiterzugehen, statt einen Offset zu verwenden, der sich ändern kann, wenn während des Prozesses Datensätze eingefügt oder gelöscht werden.

Der Fortschritt und die Änderungen des Stapels müssen aufeinander abgestimmt sein. Wenn möglich, speichere die fachlichen Änderungen und den neuen Checkpoint in derselben Transaktion. So wird bei einem Prozessabsturz vor der Bestätigung kein Fortschritt vermerkt, den die Datenbank nicht angewendet hat; bei einer Bestätigung rückt auch der Cursor weiter. Liegt der Ausführungsstatus in einem anderen System, gibt es diese automatische Atomarität nicht: Dann muss entweder eine Abstimmung entworfen oder akzeptiert werden, dass Stapel wiederholt werden; in diesem Fall müssen die wiederholten Stapel idempotent sein.

Speichere außerdem die Import-ID, den Status, den Checkpoint, Zähler und gegebenenfalls einen Verweis auf die Version oder den Fingerabdruck der Datei. Prüfe bei der Wiederaufnahme, ob es sich um dieselbe Eingabe und einen wiederherstellbaren Lauf handelt. Definiere explizite Statuswerte wie ausstehend, in Bearbeitung, abgeschlossen und fehlgeschlagen sowie eine Richtlinie zum Erkennen verwaister Läufe. Markiere einen Import nicht allein deshalb als abgeschlossen, weil der Prozess ohne Ausnahme beendet wurde: Prüfe, ob das erwartete Ende erreicht wurde.

Fehler isolieren und Wiederholungsversuche steuern

Lege im Voraus fest, ob ein ungültiger Datensatz den gesamten Import stoppen, ausgeschlossen oder zur Überprüfung markiert werden soll. Bei vorhersehbaren Formatfehlern kann es sinnvoll sein, die Daten vor dem Öffnen der Transaktion zu validieren und den Grund zusammen mit einer Zeilen-ID zu protokollieren. Bei Fehlern beim Speichern rolle den betroffenen Stapel zurück. Mit nachfolgenden Stapeln fortzufahren ist nur dann sinnvoll, wenn deren Daten unabhängig sind und der Import eindeutig als teilweise abgeschlossen ausgewiesen werden kann.

Unterscheide permanente Fehler – etwa einen fehlenden Pflichtwert – von vorübergehenden Ausfällen, wie einer behebbaren Verbindungsunterbrechung. Die Wiederholung eines permanenten Fehlers verschwendet Ressourcen und erschwert die Diagnose. Bei einem vorübergehenden Fehler kann dagegen eine begrenzte Anzahl von Versuchen mit wachsender Wartezeit sinnvoll sein. Sind die Versuche ausgeschöpft, bewahre genügend Statusinformationen und Kontext auf, um den Fehler untersuchen und den Import fortsetzen zu können, ohne die ursprüngliche Ursache zu verschleiern.

Wiederholungsversuche können Schreibvorgänge erneut ausführen, wenn sie nicht sorgfältig entworfen sind. Verwende Geschäftsschlüssel oder Quell-IDs, um bereits importierte Datensätze zu erkennen, und lege fest, ob eine Wiederholung einfügen, aktualisieren, ignorieren oder einen Konflikt melden soll. Eindeutigkeitsbedingungen in der Datenbank können diese Entscheidung absichern, ersetzen aber nicht die Geschäftslogik. Verlasse dich nicht allein auf den Checkpoint, um Duplikate zu verhindern: Er kann veraltet sein oder Änderungen, die auf anderem Weg vorgenommen wurden, nicht abdecken.

Sendet ein Stapel auch E-Mails, veröffentlicht Nachrichten oder ruft eine API auf, kann die Datenbanktransaktion diese externen Auswirkungen nicht rückgängig machen. Führe sie nicht so aus, als gehörten sie zu einer nicht vorhandenen verteilten Transaktion. Eine Alternative ist, das ausstehende Ereignis in einer transaktionalen Outbox-Tabelle zu speichern und es anschließend mit Wiederholungsversuchen und idempotenten IDs zu verarbeiten. Schlägt die externe Aktion fehl, muss der Status eine Wiederherstellung ermöglichen, ohne den Vorgang zu duplizieren oder fälschlich zu behaupten, der Stapel sei vollständig abgeschlossen.

Konsistenz, Fortschritt und Wiederherstellung testen

Die Tests sollten mehr als nur den erfolgreichen Ablauf abdecken. Simuliere Fehler vor dem Start einer Transaktion, während der Schreibvorgänge, unmittelbar vor der Bestätigung und nach der Bestätigung, aber vor der Aktualisierung eines externen Status. Prüfe, welche Daten erhalten bleiben, welcher Checkpoint bestehen bleibt und ob eine Wiederaufnahme das erwartete Ergebnis liefert. Berücksichtige doppelte Datensätze, ungültige Zeilen, leere Stapel und Fehler beim Speichern.

Miss in einem repräsentativen Test die Dauer pro Stapel, den Speicherverbrauch, die Fehlerrate, die Sperrzeit und den Fortschritt. Prüfe außerdem, ob die Zähler zwischen gelesenen, akzeptierten, abgelehnten und bestätigten Zeilen unterscheiden; „verarbeitet“ kann mehrdeutig sein, wenn darunter auch zurückgerollte Änderungen fallen. Metriken und Protokolle sollten den Import und den Stapel identifizieren, ohne sensible Daten auszugeben, die für die Diagnose nicht erforderlich sind.

Checkliste vor dem Produktionseinsatz

Checkliste vor dem Produktionseinsatz — guía visual de DedicatedPHP
  • Die Transaktionseinheit entspricht einer konsistenten fachlichen Einheit.
  • Die Stapelgröße ist konfigurierbar und wurde mit repräsentativen Daten und einer entsprechenden Last bewertet.
  • Der Checkpoint wird erst aktualisiert, wenn der zugehörige Stapel bestätigt wurde.
  • Die Wiederaufnahmestrategie verwendet einen stabilen Schlüssel und identifiziert die Quelleingabe eindeutig.
  • Permanente und vorübergehende Fehler werden unterschiedlich und nachvollziehbar behandelt.
  • Wiederholte Vorgänge sind idempotent oder erkennen Konflikte ausdrücklich.
  • Externe Auswirkungen werden mit einer unabhängigen und wiederherstellbaren Strategie verarbeitet.
  • Die Tests prüfen Fehler an verschiedenen Stellen, nicht nur einen vollständig durchgelaufenen Import.

Das Ziel ist nicht, jeden Fehler zu verhindern, sondern seine Folgen zu begrenzen und den resultierenden Status transparent zu machen. Mit durchdachten Transaktionsgrenzen, konsistenten Checkpoints und sicheren Wiederholungsversuchen lässt sich ein PHP-Import wiederherstellen, ohne teilweisen Fortschritt mit einem Abschluss zu verwechseln oder bereits bestätigte Änderungen erneut anzuwenden.

Möchten Sie diese Ideen in Ihrem Projekt anwenden?Lass uns über deine PHP-Plattform sprechen.
Verwandten Dienst anzeigen