Was sind Datenbank-Trigger (BeforeSave und AfterSave)?

Aktualisiert: September 2026

Ein Datenbank-Trigger ist ein Code-Hook, der bei Datenereignissen automatisch läuft – vor dem Speichern zum Validieren, danach zum Reagieren. Die Idee hat zwei Abstammungslinien mit einem gemeinsamen Prinzip: den klassischen SQL-Trigger, prozeduralen Code, der in der Datenbank-Engine wohnt, und den modernen Hook auf Anwendungsebene – beforeSave, afterSave, beforeDelete – JavaScript, das pro Klasse im Backend registriert wird. Beide kodieren dasselbe Versprechen: Die Regel feuert bei jedem Schreibvorgang, gleich welcher Client, welches SDK oder welches Skript ihn ausgeführt hat – und genau das kann clientseitige Validierung nie versprechen.

Das Wichtigste im Überblick

FrageAntwort
Das PrinzipCode, an Datenereignisse gebunden – automatisch, pro Tabelle/Klasse, auf jedem Schreibpfad
Before =Validieren · normalisieren · Standardwerte setzen – kann den Schreibvorgang noch ändern oder abbrechen
After =Reagieren – zählen, benachrichtigen, synchronisieren; geschrieben ist geschrieben, also idempotent bleiben
Die zwei FormenSQL-Trigger in der Engine · JS-Hooks im Backend-Prozess
Die klassischen BugsVersteckte Logik · endlose Selbstauslösung · langsame Trigger, die jeden Speichervorgang blockieren

Das Hook-Modell in der Praxis

Eine Validierungsregel und ihre Durchsetzung, von beiden Enden aus gesehen – der Server definiert sie einmal, und jeder Client überall erbt sie:

// JavaScript — Cloud Code (cloud/main.js)
// beforeSave: validate + normalize — can still change or ABORT the write
Parse.Cloud.beforeSave('Review', (req) => {
  const stars = req.object.get('stars');
  if (stars < 1 || stars > 5) throw 'Stars must be between 1 and 5';
  const comment = req.object.get('comment');
  if (comment && comment.length > 500) {
    req.object.set('comment', comment.slice(0, 497) + '…');
  }
});

// afterSave: side effects — the write already happened; be idempotent
Parse.Cloud.afterSave('Review', async (req) => {
  if (req.object.existed()) return; // count only NEW reviews, once
  await updateAverageStars(req.object.get('movie'));
});

Die vollständige Hook-Familie überträgt dieselbe Form auf den gesamten Datenlebenszyklus: beforeSave/afterSave, beforeDelete (das Löschen eines Albums verhindern, das noch Fotos enthält) und afterDelete (seine Kinder aufräumen), dazu beforeFind/afterFind, um Abfragen umzuschreiben und Felder aus Ergebnissen zu entfernen – CRUD, eingepackt.

Die klassische Form: SQL-Trigger

CREATE TRIGGER audit_price_change
AFTER UPDATE ON products
FOR EACH ROW                              -- Zeilenebene: feuert pro betroffener Zeile
WHEN (OLD.price IS DISTINCT FROM NEW.price)
EXECUTE FUNCTION log_price_change();      -- OLD und NEW halten beide Versionen

Die Taxonomie, die alle Datenbanken teilen, gemäß den Referenzen von PostgreSQL und MySQL: der Zeitpunkt – BEFORE (darf NEW ändern oder abbrechen), AFTER (reagiert auf die geschriebene Zeile), INSTEAD OF (ersetzt die Operation, vor allem bei Views); das Ereignis – Insert, Update, Delete; die Granularität – Zeilenebene gegenüber Anweisungsebene (ein Update über 10 Zeilen feuert einen Zeilen-Trigger 10-mal, einen Anweisungs-Trigger einmal). Zwei Semantiken zum Einprägen: SQL-Trigger laufen in derselben Transaktion wie der Schreibvorgang – scheitert der Trigger, wird die gesamte Operation zurückgerollt – und AFTER-Trigger feuern nur für Schreibvorgänge, die tatsächlich erfolgreich waren.

Before vs. after: die Wahl richtet sich nach der Aufgabe

KriteriumBefore-HooksAfter-Hooks
Kann die Daten ändernJa – mutieren, Standardwert setzen, abschneidenNein – es ist geschrieben
Kann den Schreibvorgang abbrechenJa – Fehler werfen, und der Speichervorgang scheitertNein
Richtig fürValidierung, Normalisierung, berechnete FelderZähler, Benachrichtigungen, Synchronisation, Audit
Falsch fürNebenwirkungen – scheitert der Speichervorgang danach, ist die Wirkung schon eingetretenAlles, was den Schreibvorgang hätte blockieren sollen
Verhalten im FehlerfallWeist die Operation ab, Fehler an den ClientOft Fire-and-forget – Fehler landen in den Logs
DisziplinSchnell – er blockiert jeden SpeichervorgangIdempotent – er läuft womöglich erneut

Die Folgerungen, die kein Erklärtext ausspricht: Eine Nebenwirkung in einem Before-Hook ist ein Bug per Konstruktion (die E-Mail geht raus, dann scheitert der Speichervorgang), und ein nicht idempotenter After-Hook ist ein doppelter Zähler, der auf seinen Wiederholungsversuch wartet. In Hook-Systemen wie dem von Back4app läuft afterSave zu Ende, nachdem der Client seine Antwort bereits erhalten hat – Reaktionen sind von Natur aus asynchron, ihre Fehler müssen also verkraftbar und protokolliert sein.

Lebenszyklus eines Schreibvorgangs durch Before- und After-HooksEin Schreibvorgang von einem beliebigen Client durchläuft zuerst den Before-Hook, der ihn validieren, verändern oder abbrechen kann. Wird er zugelassen, schreibt die Datenbank ihn fest, und der After-Hook reagiert anschließend mit Nebenwirkungen wie Zählern, Benachrichtigungen und Webhooks, die idempotent sein müssen, weil sie mehr als einmal laufen können.

throw

zulassen (ggf. geändert)

Beliebiger Client
SDK · REST · Skript

beforeSave
validieren · normalisieren

Speichern abgelehnt –
Fehler an den Client

Schreibvorgang wird festgeschrieben

afterSave
Nebenwirkungen, idempotent

Zähler · Benachrichtigungen ·
ausgehende Webhooks

Ein Schreibvorgang von einem beliebigen Client durchläuft zuerst den Before-Hook, der ihn validieren, verändern oder abbrechen kann. Wird er zugelassen, schreibt die Datenbank ihn fest, und der After-Hook reagiert anschließend mit Nebenwirkungen wie Zählern, Benachrichtigungen und Webhooks, die idempotent sein müssen, weil sie mehr als einmal laufen können.

Hooks vs. SQL-Trigger

KriteriumHooks auf Anwendungsebene (beforeSave/afterSave)SQL-Trigger
SpracheJavaScript plus das ganze SDK und sein ÖkosystemSQL / prozedurale SQL-Dialekte
Externe AufrufeJa – APIs, Push, WebhooksPraktisch nein – und es ist nicht ihre Aufgabe
Lebt inIhrer Codebasis: versioniert, testbar, deploytDem Schema: in der Datenbank
TransaktionBefore-Hooks bewachen den Schreibvorgang; After-Hooks laufen nach der AntwortDieselbe Transaktion – ein Fehler rollt alles zurück
BindetJede Anfrage über die Backend-APIJeden Schreibvorgang auf der Tabelle, woher auch immer
Blinder FleckDirekte Schreibvorgänge in die Datenbank umgehen sieLogik, die für Anwendungs-Debugger unsichtbar ist

Die letzte Zeile ist die ehrliche Symmetrie: Die Garantie jeder Form endet an ihrer Schicht. Ein SQL-Trigger erwischt selbst eine wildgewordene psql-Sitzung, verbirgt die Logik aber vor dem Anwendungswerkzeug; ein Hook auf API-Ebene bindet jeden Client-Pfad durch das Backend, nicht aber den direkten Datenbankzugriff – weshalb Plattformen, denen das API-Gateway gehört (aller Verkehr fließt hindurch), in der Praxis das Beste aus beiden Welten bekommen. Die Fußnote zu ORMs gehört ebenfalls hierher: ORM-Hooks feuern nur über den ORM – Massenoperationen und rohes SQL laufen einfach daran vorbei.

Die Fallstricke, ehrlich benannt

Versteckte Logik ist der Klassiker: Ein Entwickler debuggt stundenlang seinen eigenen Code, während ein Trigger im Stillen Werte umschreibt – Trigger sind an der Aufrufstelle unsichtbar, dokumentieren Sie sie also und halten Sie ihre Zahl klein. Endlosschleifen: Ein Trigger, der in seine eigene Tabelle schreibt (oder ein afterSave, das sein eigenes Objekt speichert), löst sich selbst erneut aus; prüfen Sie, was sich geändert hat, und geben Sie der Rekursion eine Abbruchbedingung, bevor sie selbst eine findet. Synchrone Kosten: Before-Hooks sitzen in der Latenz jedes Schreibvorgangs – ein Hook von 200 ms macht jeden Speichervorgang 200 ms langsamer, und Massenschreibvorgänge multiplizieren die Auslösungen auf Zeilenebene mit der Zeilenzahl. Kaskadenketten: Trigger, die Trigger auslösen, die Trigger auslösen, machen aus einem Insert ein archäologisches Projekt. Die Dachregel aus Jahrzehnten der Praxis: Trigger setzen Regeln durch; sobald einer anfängt, einen Ablauf zu orchestrieren, verlagern Sie den Ablauf in Funktionen oder Jobs und lassen den Trigger nur noch in die Queue einreihen.

Typische Anwendungsfälle

  • Validierung, die jeder Client befolgt – die Regel “Sterne zwischen 1 und 5”, durchgesetzt gegen gefälschte Anfragen ebenso wie gegen künftige SDKs.
  • Audit-Spuren – wer hat wann was geändert, geschrieben vom Ereignis selbst statt von kooperativen Clients.
  • Denormalisierte Zähler und berechnete Felder – Durchschnitte, Anzahlen und suchfreundliche Duplikate, zum Schreibzeitpunkt aktuell gehalten.
  • Integrität in Kaskaden – Löschvorgänge verweigern, solange Kinder existieren, oder die Kinder danach aufräumen.
  • Reaktive Nebenwirkungen – ein afterSave, das eine Push-Benachrichtigung oder einen ausgehenden Webhook auslöst: aus dem Datenbankereignis wird ein Integrationsereignis.

Welcher Hook wofür? Entscheidungsmatrix

Die AufgabeDer Hook
Ungültige Daten abweisenbeforeSave – Fehler werfen
Kürzen, Standardwerte setzen, kanonisierenbeforeSave – Objekt mutieren
Einen Zähler oder ein Aggregat aktualisierenafterSave – idempotent
Eine Person oder ein System benachrichtigenafterSave → Push / Webhook / Queue
Gefährliche Löschvorgänge blockierenbeforeDelete
Nach Löschvorgängen aufräumenafterDelete
Abfragen pro Nutzer eingrenzenbeforeFind
Lange oder langsame ReaktionafterSave reiht einen Job ein – nie die Arbeit inline erledigen

Grenzen und Trade-offs

  • Unsichtbarkeit ist der Preis der Automatik. Logik, die niemand aufruft, ist Logik, an die sich niemand erinnert; Benennung, Dokumentation und Code-Review halten die Magie prüfbar.
  • Hooks reichen nur so weit wie ihre Schicht. API-Hooks übersehen direkte Schreibvorgänge in die Datenbank; SQL-Trigger übersehen nichts, verstecken sich aber vor Ihrem Werkzeug – wissen Sie, welchen blinden Fleck Sie gewählt haben.
  • Die Schreiblatenz ist das Budget. Jeder Before-Hook zehrt davon; messen Sie Hooks so, wie Sie Abfragen messen.
  • After-Hooks sind letztendlich konsistent. Zähler hinken Millisekunden hinterher und können doppelt feuern – gestalten Sie Lesevorgänge (und Wiederholungsversuche) entsprechend.
  • Trigger ersetzen keine Constraints. Eindeutige Indizes, Fremdschlüssel und ACLs greifen früher und billiger; Trigger übernehmen dort, wo deklarative Regeln aufhören.

Trigger mit Back4app

Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Trigger sind hier die Datenereignis-Familie von Cloud Code: Registrieren Sie Parse.Cloud.beforeSave('Review', …) einmal – die Code-Tabs zeigen das vollständige Muster – und die Regel bindet jeden Schreibvorgang, der über REST, GraphQL, ein beliebiges SDK oder das Dashboard hereinkommt, weil das API-Gateway der einzige Weg zu den Daten ist. Hooks erhalten reichhaltigen Kontext (request.object, request.original, request.user, Master-Key-Status), sodass die Validierung für Administratoren abweichen kann, beforeFind Abfragen zusätzlich zu den ACLs pro Nutzer eingrenzen kann und After-Hooks das gesamte JavaScript-Ökosystem für die Reaktionen zur Verfügung haben, die SQL-Trigger nicht erreichen – Push-Benachrichtigungen, ausgehende Webhooks, Einreihungen in Job-Queues. Mit Ihrem Code deployt, in git versioniert, testbar wie jede Funktion: die Garantie des Triggers, ohne seine Archäologie.

Häufige Fragen

Was ist ein Datenbank-Trigger?

Prozeduraler Code, der automatisch ausgeführt wird, sobald ein Datenereignis – Insert, Update, Delete – auf einer bestimmten Tabelle oder Klasse eintritt. Die klassische Form lebt in der SQL-Datenbank; die moderne Form auf Anwendungsebene ist eine Hook-Funktion wie beforeSave oder afterSave, die das Backend um jeden Schreibvorgang herum ausführt.

Was ist der Unterschied zwischen BEFORE- und AFTER-Triggern?

Zeitpunkt und Befugnisse. BEFORE läuft vor dem Schreibvorgang und kann die eingehenden Daten validieren, verändern oder die Operation ganz abbrechen. AFTER läuft, nachdem der Schreibvorgang erfolgreich war – es kann nichts mehr ändern, nur noch reagieren: protokollieren, zählen, benachrichtigen. AFTER feuert nie für Schreibvorgänge, die fehlgeschlagen sind.

Was ist der Unterschied zwischen einem Trigger und einer Stored Procedure?

Der Aufruf. Eine Stored Procedure wird explizit aufgerufen, nimmt Parameter entgegen und liefert Ergebnisse zurück. Ein Trigger wird nie aufgerufen – er feuert automatisch, wenn sein Ereignis eintritt, ohne Parameter, an eine Tabelle gebunden. Dieselbe prozedurale Maschinerie, das umgekehrte Aktivierungsmodell.

Gehört Logik in Trigger oder in den Anwendungscode?

Der Konsens ist hybrid: Trigger (oder Hooks) für Regeln, die auf jedem Schreibpfad gelten müssen – Validierung, Integrität, Audit – und Anwendungsdienste für komplexe Abläufe. Hooks auf Anwendungsebene sind der moderne Mittelweg: die Garantien eines Triggers, eine echte Programmiersprache, Versionskontrolle.

Beeinträchtigen Trigger die Performance?

Sie laufen synchron im Schreibpfad, also verlangsamt ein langsamer Trigger jeden Speichervorgang, und Trigger auf Zeilenebene vervielfachen sich bei Massenoperationen – ein Update über hunderttausend Zeilen feuert hunderttausendmal. Halten Sie Before-Hooks schlank und verlagern Sie langsame Reaktionen in After-Hooks oder Hintergrund-Jobs.

Kann ein Trigger eine Endlosschleife auslösen?

Der Klassiker – ein Trigger, der in seine eigene Tabelle schreibt, löst sich selbst erneut aus, und ein afterSave, das das gerade verarbeitete Objekt speichert, ruft sich rekursiv auf, bis etwas bricht. Schützen Sie sich, indem Sie vor dem Schreiben prüfen, was sich tatsächlich geändert hat, und speichern Sie das auslösende Objekt nie ohne Abbruchbedingung aus seinem eigenen After-Hook heraus erneut.

Können Trigger externe Dienste aufrufen?

SQL-Trigger können praktisch nicht aus der Datenbank heraus – und sollten es auch nicht. Das ist der große Vorteil von Hooks auf Anwendungsebene: Ein afterSave in JavaScript kann eine Push-Benachrichtigung senden, jede beliebige API aufrufen oder einen ausgehenden Webhook auslösen, weil es im Backend-Prozess mit dem vollständigen Ökosystem läuft.

Wofür wird beforeSave verwendet?

Für die drei Aufgaben, die vor dem Schreibvorgang laufen müssen: Validierung (werfen Sie einen Fehler, und der Speichervorgang scheitert – für jeden Client), Normalisierung (Felder kürzen, abschneiden, kanonisieren) sowie Standard- und berechnete Werte. Nebenwirkungen gehören nicht dorthin – scheitert der Speichervorgang danach, ist die Wirkung längst eingetreten.

Verwandte Begriffe

Vergleichen mit

Weiterführende Quellen

Bereit, Ihr Backend zu bauen?

Starten Sie Ihr Projekt auf Back4app in wenigen Minuten — Datenbank, Authentifizierung, APIs und Cloud Code inklusive. Keine Kreditkarte erforderlich.

Geschrieben und geprüft von Back4app Engineering, Back4app Engineering · Veröffentlicht am 2026-09-25