Doppelte Aktionen bei Webhooks und APIs verhindern: Stabiler Idempotenzschlüssel pro Aktion; Event-ID erkennt nur gleiche Zustellung.; Stripe speichert Status/Antwort des ersten Aufrufs; gleicher Schlüssel liefert dasselbe.; PostgreSQL: ON CONFLICT DO NOTHING verhindert doppelte Einfügung bei gleichem Schlüssel.
Bild: Arbeitsfluss

Fehlerbehandlung

Doppelte Aktionen verhindern

So schützen Sie Workflows vor doppelten Rechnungen und anderen Aktionen: fachliche Schlüssel, sichere Speicherung, Wiederholungsversuche und Tests.

Erhält ein Workflow denselben Auslöser erneut, darf daraus nicht ungeprüft eine zweite Rechnung, Benachrichtigung oder andere fachliche Wirkung entstehen. Geben Sie jeder solchen Aktion einen stabilen Schlüssel und protokollieren Sie, ob sie bereits läuft oder welches Ergebnis sie erzeugt hat.

Zustellung, Vorgang und Ergebnis unterscheiden

Ein Webhook kann erneut zugestellt, eine Nachricht erneut verarbeitet oder ein Formular zweimal abgesendet werden. Mehrere Zustellungen können zu einem Vorgang gehören; umgekehrt können zwei ähnlich aussehende Vorgänge beide berechtigt sein. Entscheidend ist die beabsichtigte Aktion, nicht die Zahl der eingegangenen Nachrichten.

Eine Ereignis-ID erkennt die erneute Zustellung desselben Ereignisses. Können verschiedene Ereignisse dieselbe Folgeaktion auslösen, braucht diese Aktion einen eigenen Schlüssel, etwa die Kombination aus Auftragskennung, Aktion und fachlich festgelegter Version. Eine beim Wiederholungsversuch neu erzeugte Kennung erfüllt diesen Zweck nicht.

Zustellung, Vorgang und Ergebnis abgrenzen

Zustellung
Dasselbe Ereignis kann mehrfach eintreffen. Eine Ereignis-ID erkennt die erneute Zustellung.
Vorgang
Fachlich beabsichtigte Aktion. Braucht einen eigenen Schlüssel, etwa Auftragskennung, Aktion und Version.
Ergebnis
Gespeicherte Ergebniskennung. Ein erneuter Lauf kann das vorhandene Ergebnis zuordnen.

Idempotenz als Vertrag verstehen

Idempotenz heißt: Mehrere identische Anfragen wirken wie eine einzelne. Das bedeutet nicht „der Workflow läuft nur einmal“. In verteilten Systemen gibt es sowohl Aktionen, die höchstens einmal gesendet werden, als auch wiederholtes Senden bis zur Erfolgsbestätigung. Eine idempotente API unterstützt Wiederholungen, indem sie den Schlüssel einer Anfrage zuordnet.

Für die Integration zählt, was der Dienst tatsächlich zusichert. Stripe speichert bei einer idempotenten Anfrage Statuscode und Antwortinhalt des ersten ausgeführten Aufrufs und gibt dieses Ergebnis bei Wiederholung mit demselben Schlüssel zurück. Eine erneute Anfrage kann dieselbe Antwort liefern, auch wenn sich der zugrunde liegende Zustand inzwischen geändert hat.

Schlüssel einheitlich und stabil wählen

Ein Zeitstempel ist kein verlässlicher Idempotenzschlüssel: Abweichende Uhren oder mehrere Clients mit demselben Zeitstempel können zu Ungenauigkeiten führen. Uneinheitliche Schlüsselbildung über mehrere Dienste kann dazu führen, dass Wiederholungen nicht als solche erkannt werden. Legen Sie fest, welche fachliche Aktion der Schlüssel bezeichnet, und wenden Sie die Regel konsistent an.

Der Schlüssel sollte keine sensiblen Angaben wie E-Mail-Adresse oder persönliche Kennung enthalten. Stripe empfiehlt zufällige Schlüssel mit genügend Entropie, etwa UUIDs der Version 4. Bei Stripe sind Idempotenzschlüssel auf 255 Zeichen begrenzt; diese Vorgaben gelten für diese API und nicht automatisch für andere Zielsysteme.

Stripe-Idempotenzschlüssel: Grenzen und Empfehlungen

Maximale Schlüssellänge
255 Zeichen
Automatische Entfernung
ab 24 Stunden
Empfohlene Schlüsselform
zufällige UUID v4
Unterstützte Operationen
alle POST-Anfragen

Zustand und Wirkung zusammen planen

Die Abfrage „Schon vorhanden?“ schützt allein nicht gegen zwei gleichzeitige Läufe: Beide können zunächst „nein“ lesen. Wo der gemeinsame Zustand gespeichert wird, sollte eine passende Eindeutigkeitsregel die gleichzeitige Anlage desselben Schlüssels verhindern. PostgreSQL kann eine zweite Einfügung bei entsprechendem Konflikt mit ON CONFLICT DO NOTHING auslassen. Die Datenbank entscheidet dabei nicht, welcher fachliche Schlüssel richtig ist.

Speichern Sie zum Schlüssel den Bearbeitungsstatus und, sobald bekannt, die Ergebniskennung. Ein erneuter Lauf kann ein vorhandenes Ergebnis zuordnen. „Läuft“ ist noch kein Erfolg; nach einem Fehler oder einer unklaren Antwort braucht es eine festgelegte Wiederaufnahme oder Prüfung.

Liegt die Zustandsablage in einem anderen System als die externe Aktion, kann die lokale Eindeutigkeitsregel diese Aktion nicht allein absichern. Prüfen Sie, ob die Ziel-API einen Idempotenzschlüssel annimmt oder ob sich ihr Ergebnis über eine stabile Referenz zuverlässig wiederfinden lässt. Unterstützte Operationen und Aufbewahrungsdauer unterscheiden sich je nach Anbieter.

Ablauf zur Absicherung gegen doppelte Wirkung

  1. Fachlichen Idempotenzschlüssel bildenKombination aus Auftragskennung, Aktion und fachlich festgelegter Version – keine neu erzeugte Kennung beim Wiederholungsversuch.
  2. Schlüssel mit Bearbeitungsstatus persistierenStatus ‚läuft‘ oder ‚abgeschlossen‘ sowie die Ergebniskennung speichern.
  3. Eindeutigkeitsregel in der Datenbank anwendenGleichzeitige Anlage desselben Schlüssels verhindern, z. B. mit PostgreSQL ON CONFLICT DO NOTHING.
  4. Externe API mit Idempotenzschlüssel aufrufenFalls die Ziel-API keinen Schlüssel annimmt, eine stabile Referenz zum Wiederfinden des Ergebnisses nutzen.
  5. Ergebniskennung speichern und Aufbewahrung festlegenLokale Zustandsdauer an die Wiederholungsdauer und den Vertrag der Ziel-API anpassen.
  6. Unklare Antwort behandelnFestgelegte Wiederaufnahme oder manuelle Prüfung statt blinder Neuanlage.

Antwort und Schlüssel gemeinsam betrachten

Ein Idempotenzdienst speichert nicht zwingend schon jede eingehende Anfrage. Stripe speichert das Ergebnis erst, wenn die Ausführung eines Endpunkts begonnen hat. Anfragen, deren Parameter die Validierung nicht bestehen, oder solche, die mit einer gleichzeitig laufenden Anfrage kollidieren, erhalten dort kein gespeichertes Idempotenz-Ergebnis.

Die Aufbewahrung gehört zum Verhalten des Zielsystems: Stripe kann Schlüssel automatisch entfernen, sobald sie mindestens 24 Stunden alt sind. Wird ein Schlüssel danach erneut verwendet, behandelt Stripe die Anfrage als neu. Lokale Zustandsdauer und Wiederholungsdauer sollten zum Vertrag der Ziel-API passen; ein abgelaufener externer Schlüssel ersetzt keine eigene fachliche Zuordnung.

Anfrageparameter und Ergebnis prüfen

Ein wiederverwendeter Schlüssel muss zur ursprünglichen Anfrage passen. Stripe vergleicht die eingehenden Parameter mit denen des ersten Aufrufs und meldet einen Fehler, wenn sie abweichen. So steht derselbe Schlüssel nicht versehentlich für eine andere Aktion oder andere Eingabedaten.

Prüfen Sie für jedes Zielsystem, welche Operationen einen Idempotenzschlüssel unterstützen. Bei Stripe akzeptieren alle POST-Anfragen solche Schlüssel; bei GET- und DELETE-Anfragen haben sie keine Wirkung, da diese dort bereits idempotent sind. Übertragen Sie die Regel nicht ungeprüft auf andere APIs, sondern dokumentieren Sie pro Zielsystem die unterstützten Operationen und die Bedeutung der Antwort.

Den gesamten Ablauf prüfen

Testen Sie mit geeigneten Testdaten den ersten Durchlauf, eine erneute Zustellung, zwei gleichzeitige Läufe, eine verlorene Antwort nach erfolgreicher Anlage und einen bewusst neuen Vorgang mit ähnlichen Daten. Zählen Sie die tatsächlichen Ergebnisse im Zielsystem, nicht nur erfolgreiche Workflow-Läufe.

Bewahren Sie Schlüssel und Ergebniszuordnungen so lange auf, wie relevante Wiederholungen eintreffen können. Nach dem Löschen eines Schlüssels kann ein alter Versuch sonst wie ein neuer Vorgang behandelt werden. Für Fälle, deren Ergebnis sich nicht eindeutig feststellen lässt, ist eine manuelle Prüfung sicherer als eine blinde Neuanlage.

Ergänzen Sie die Tests um eine Wiederholung mit identischem Schlüssel und identischen Parametern sowie um denselben Schlüssel mit veränderten Parametern. Prüfen Sie, ob das Zielsystem das gespeicherte Ergebnis zurückgibt oder die abweichende Anfrage zurückweist. Damit wird sichtbar, ob der Schlüssel tatsächlich die beabsichtigte Aktion abgrenzt.

Speichern Sie nicht vorsorglich den vollständigen Anfrageinhalt für jede Wiederholung. AWS nennt das Überschreiben und Speichern vollständiger Nutzdaten als mögliches Leistungs- und Skalierungsproblem. Für die Zuordnung sind vor allem ein konsistent erzeugter Schlüssel, der Bearbeitungsstatus und das Ergebnis relevant.

Testfälle für doppelte Aktionen

  • Erster Durchlauf mit geeigneten Testdaten
  • Erneute Zustellung desselben Ereignisses
  • Zwei gleichzeitige Läufe
  • Verlorene Antwort nach erfolgreicher Anlage
  • Bewusst neuer Vorgang mit ähnlichen Daten
  • Wiederholung mit identischem Schlüssel und identischen Parametern
  • Derselbe Schlüssel mit veränderten Parametern
  • Ergebnisse im Zielsystem zählen, nicht nur erfolgreiche Workflow-Läufe

In diesem Leitfaden

  1. Einen eindeutigen Schlüssel für ein Ereignis wählenWelche Ereigniskennung erkennt echte Wiederholungen? Prüfen Sie Stabilität, fachlichen Geltungsbereich, neue Vorgänge und widersprüchliche Parameter.
  2. Rechnungen nach einem Wiederholungsversuch nicht erneut anlegenNach einem Timeout kann eine Rechnung bereits existieren. So ordnen Sie den ursprünglichen Auftrag zu und vermeiden eine zweite Anlage.
  3. Wiederholte Ereignisse von neuen Vorgängen unterscheidenErkennen Sie, wann ein Ereignis erneut zugestellt wurde und wann ein neuer Geschäftsvorgang vorliegt. Mit fachlicher Regel und prüfbaren Fällen.
  4. Schutz vor Duplikaten vor dem Produktivstart testenPrüfen Sie Duplikatschutz mit Wiederholungen, parallelen Läufen, verlorenen Antworten und neuen Vorgängen. Mit Soll-Matrix für Testdaten.

Mehr aus Fehlerbehandlung

Fehlerbehandlung

Datenrisiken vor einer Freigabe prüfen und dokumentieren

Datenwege, Konten, Empfänger und Aufbewahrung vor dem Produktivstart einer internen Automation prüfen und offene Datenschutzfragen klären.

Fehlerbehandlung

Fehler mit ausreichendem Kontext protokollieren

Erfassen Sie Vorgang, Versuch, Schritt und bekannten Ausgang eines Workflow-Fehlers, ohne Geheimnisse oder unnötige Rohdaten mitzuschreiben.