- ein System entwerfen, in dem Korrektheit wichtiger ist als Geschwindigkeit
- Überbuchungen durch Sperren, bedingte Updates und Reservierungen verhindern
- Zahlungen, Webhooks und Benachrichtigungen zuverlässig einbinden
- Lastspitzen bei begehrten Terminen abfangen
Buchungssysteme begegnen uns überall: Termine beim Friseur, Kurse im Yogastudio, Zimmer im Hotel, Tickets für Konzerte. Ihnen allen ist eine besondere Eigenschaft gemeinsam: Ein Platz darf nur einmal vergeben werden. Anders als beim Kurzlink-Dienst oder im Chat, wo Geschwindigkeit im Vordergrund steht, geht hier Korrektheit vor. Eine Überbuchung verärgert Kunden, kostet Geld und Vertrauen. Diese Fallstudie entwirft eine Buchungsplattform, über die viele Studios ihre Kurse anbieten – mit Wartelisten, Online-Zahlung und Erinnerungen.
1. Anforderungen
Funktional: Studios legen Kurse mit Terminen und Platzzahl an. Kunden sehen freie Plätze, buchen, bezahlen online oder per Guthaben, stornieren bis zu einer Frist und können sich auf eine Warteliste setzen. Bei einer Stornierung rückt die erste Person der Warteliste automatisch nach. Erinnerungen gehen am Vortag per E-Mail oder Push. Nicht funktional: Keine Überbuchungen, niemals. Keine doppelten Buchungen oder Zahlungen. Die Plattform muss Spitzen aushalten, etwa wenn ein beliebtes Studio montags um acht Uhr die Kurse der Woche freischaltet. Studios sind Mandanten, deren Daten streng getrennt sind.
2. Überschlag
60.000
Buchungen am Tag
0,7/s
Durchschnitt
40/s
Spitze
1.200.000
Leseanfragen am Tag (≈ 20×)
Die Durchschnittswerte sind unspektakulär; eine einzige gut eingerichtete Datenbank bewältigt sie mühelos. Die eigentliche Herausforderung ist die Konzentration: Viele Menschen wollen im selben Moment dieselben wenigen Plätze. Das ist kein Mengen-, sondern ein Konkurrenzproblem – und genau dort muss der Entwurf ansetzen.
3. API und Datenmodell
Das Datenmodell besteht aus Studios, Kursen, Terminen mit Kapazität, Buchungen mit Status und Wartelisten-Einträgen, jeweils mit Studio-Kennung für die Mandantentrennung. Buchungen durchlaufen Zustände: reserviert, bestätigt, storniert, verfallen. Die Schnittstelle bietet unter anderem POST /termine/:id/buchungen mit Idempotenzschlüssel und DELETE /buchungen/:id. Die zentrale Frage lautet: Wie verhindert man, dass zwei gleichzeitige Anfragen denselben letzten Platz erhalten? Probieren Sie es aus:
Anna, 18:02:01.120
✓ gebucht
Yoga am Abend
13 / 12
Ben, 18:02:01.124
✓ gebucht
Die robusteste einfache Lösung ist ein bedingtes Update direkt in der Datenbank: „Erhöhe die Zahl der belegten Plätze um eins, aber nur, wenn sie danach die Kapazität nicht übersteigt.“ Die Datenbank führt diese Anweisung atomar aus; genau eine der beiden Anfragen gewinnt. Ergänzend verhindert ein eindeutiger Index, dass dieselbe Person denselben Termin zweimal bucht.
4. Architektur
5. Vertiefung
Spitzen: Wenn ein beliebtes Studio seine Kurse freischaltet, konzentriert sich die Last auf wenige Datenbankzeilen. Das bedingte Update hält diese Sperren nur Millisekunden, sodass Hunderte Buchungen pro Sekunde auf einem Termin möglich sind. Bei noch größeren Ansturmen – etwa bei Konzerttickets – kommt ein virtueller Warteraum hinzu, der Besucher in Reihenfolge einlässt. Lesen: Die Anzeige freier Plätze darf leicht veraltet sein und kommt aus dem Cache; verbindlich ist nur die Prüfung beim Buchen. Zeitzonen: Termine werden mit Zeitzone gespeichert, sonst verschieben sich Kurse bei der Zeitumstellung. Wartelisten: Das Nachrücken ist ein eigener, idempotenter Vorgang, der bei jeder Stornierung und jedem Verfall ausgelöst wird. Üben Sie die Beurteilung einzelner Entscheidungen:
Die Zahlung wird innerhalb der Datenbanktransaktion beim Zahlungsanbieter ausgelöst
Die Bestätigungsmail wird über die Outbox-Tabelle verschickt
Die Kursübersicht zeigt freie Plätze aus einem Cache mit 30 Sekunden Lebensdauer
Der Zahlungs-Webhook wird ohne Signaturprüfung verarbeitet
Die Buchungs-API akzeptiert einen Idempotenzschlüssel
6. Abwägungen
| Entscheidung | Gewinn | Preis |
|---|---|---|
| Platz für 10 Minuten halten | faire Bezahlung ohne Überbuchung | Plätze kurzzeitig blockiert |
| bedingtes Update statt verteilter Sperre | einfach, atomar, schnell | Last konzentriert sich auf eine Zeile |
| freie Plätze aus dem Cache | schnelle Übersichten | Anzeige kann Sekunden alt sein |
| eine Datenbank für alle Studios | einfacher Betrieb | große Mandanten brauchen später eigene Grenzen |
Diese Architektur trägt eine Plattform mit Hunderten Studios und Zehntausenden Buchungen am Tag auf einer einzigen Postgres-Datenbank mit Replikat. Sie ist bewusst konservativ: Wo Geld und knappe Plätze im Spiel sind, schlagen bewährte Transaktionen jede ausgefallene Architektur. Die Komplexität steckt nicht in vielen Diensten, sondern in sorgfältig durchdachten Zuständen und Übergängen – genau dort, wo sie hingehört.
7. Varianten der Aufgabe
Die Grundmuster dieser Fallstudie gelten für viele Buchungssysteme, doch jede Branche bringt eigene Besonderheiten mit. Ein Hotel vergibt nicht einzelne Plätze, sondern Zimmer über mehrere Nächte; die Verfügbarkeit muss für jeden Tag des Aufenthalts geprüft werden, und Buchungsportale greifen gleichzeitig auf dieselben Zimmer zu. Eine Zahnarztpraxis bucht Termine unterschiedlicher Länge in einen Kalender mit mehreren Behandlungsräumen und muss Pufferzeiten und Notfälle berücksichtigen. Ein Konzertveranstalter verkauft nummerierte Sitzplätze an Zehntausende Menschen in wenigen Minuten; hier sind virtuelle Warteräume, das kurzzeitige Halten gewählter Plätze und ein Schutz gegen automatisierte Käufe entscheidend.
Allen gemeinsam ist das Muster aus knapper Ressource, kurzzeitiger Reservierung, externer Zahlung und verbindlicher Bestätigung. Wer dieses Muster einmal verstanden hat, kann es auf neue Branchen übertragen und sich auf deren Besonderheiten konzentrieren.
8. So präsentieren Sie den Entwurf
Bei Buchungssystemen erwarten Zuhörer, dass die Frage der Überbuchung früh und präzise beantwortet wird. Nennen Sie die Lösung konkret – etwa das bedingte Update mit der Bedingung, dass die Kapazität nicht überschritten wird – und erklären Sie, warum sie auch bei vielen gleichzeitigen Anfragen korrekt ist. Beschreiben Sie anschließend den Lebenszyklus einer Buchung mit ihren Zuständen und Übergängen; ein kleines Zustandsdiagramm sagt hier mehr als viele Worte. Zeigen Sie zum Schluss, was bei Fehlern passiert: bei einer abgebrochenen Zahlung, einem doppelt eintreffenden Webhook, einem ausgefallenen Mailserver. Diese Fehlerfälle sind der eigentliche Prüfstein, denn der Normalfall funktioniert in fast jedem Entwurf.
- [1]PostgreSQL Global Development Group (2026): Explicit Locking; Transaction Isolation. PostgreSQL Documentation.
- [2]Richardson, C. (2018): Microservices Patterns. Shelter Island: Manning (Transactional Outbox, Saga).
- [3]Stripe Inc. (2026): Webhooks – Verify Signatures; Idempotent Requests.
- [4]Kleppmann, M. (2017): Designing Data-Intensive Applications. Sebastopol: O'Reilly, Kap. 7.
Stand: September 2026. Kursmaterial der Klarwerk Akademie. Zahlen zu Latenzen und Kosten sind Größenordnungen zur Orientierung, keine Messwerte.