Kurzantwort
Doppelbuchungen verhindern Sie, indem Ihre Website freie Zeiten nicht nur beim Anzeigen prüft, sondern erneut beim Speichern – gegen eine einzige führende Quelle, die auch Telefon- und Kalendertermine kennt. Eine Regel in der Datenbank weist überlappende Termine ab, eine Vorgangskennung verhindert doppelte Termine durch Doppelklicks. Die Bestätigung geht erst nach dem Speichern hinaus. Für verbleibende Konflikte legen Sie vorab einen Klärungsweg fest.
Wie Doppelbuchungen entstehen
Eine Doppelbuchung heißt hier: Ein Zeitfenster, das nur einmal vergeben werden kann, wird zweimal zugesagt oder doppelt angelegt. Es geht um Termine von Dienstleistern wie Werkstätten und Salons, nicht um Ferienunterkünfte. Typische Ursachen:
- Gleichzeitige Anfragen: Zwei Personen buchen fast zeitgleich dieselbe Zeit. In PostgreSQL sieht eine Abfrage im Standardmodus nur Daten, die vor ihrem Beginn festgeschrieben wurden Quelle 1 . Die noch laufende Buchung der anderen Person bleibt unsichtbar, beide Prüfungen melden „frei“.
- Prüfung nur beim Anzeigen: Wer die Seite früher geladen hat, bucht auf Grundlage eines veralteten Stands.
- Verzögerter Kalenderabgleich: Direkte Kalendereinträge kennt die Website erst nach dem nächsten Abgleich. Benachrichtigungen über Änderungen sind laut Google nicht vollständig zuverlässig Quelle 2 .
- Mehrere Kanäle: Telefon, E-Mail und Website führen eigene Listen, die zusammen nicht passen.
- Wiederholte Übermittlung: Doppelklick, Neuladen oder ein Verbindungsabbruch schickt dieselbe Buchung zweimal.
- Manuelle Einträge ohne Sperre: Ein Telefontermin wird im Kalender eingetragen, während die Website dieselbe Zeit vergibt.
- Zeitumstellung und Zeitzonen: In den Umstellungsnächten fehlt eine Stunde, oder sie erscheint zweimal Quelle 3 . Eine Uhrzeit ohne Zeitzone ist dann nicht eindeutig.
So verhindern Sie Doppelbuchungen
Die Maßnahmen greifen ineinander. Den Grundsatz nennt bereits der Vergleich eigene Terminbuchung oder fertiger Dienst: Eine angezeigte freie Zeit muss beim Abschluss erneut geprüft und verlässlich reserviert werden. Hier folgt die Umsetzung.
Eine führende Quelle festlegen
Bestimmen Sie, wo ein Termin als vergeben gilt: in der Buchungsdatenbank Ihrer Website oder in Ihrem Arbeitskalender. Dort landen alle Termine, auch telefonische und die der Laufkundschaft. Ein Papierkalender daneben unterläuft jede technische Sicherung. Lässt sich ein Kanal nicht anbinden, trennen Sie die Kontingente, etwa mit festen Zeiten nur für Telefonbuchungen.
Bei Insektenschutz Gera bleibt Google Kalender der Arbeitsort: Die Buchung berücksichtigt belegte Zeiten und Blocker, die der Betrieb dort einträgt. Allgemein gilt: Ist der Kalender führend, fragt die Website dessen belegte Zeiträume ab; die Google Calendar API liefert sie für einen gewählten Zeitraum Quelle 4 . Diese API-Integration braucht eigene Fehlerwege.
Beim Speichern erneut prüfen
Die Liste freier Zeiten ist eine Momentaufnahme. Prüfen Sie beim Absenden erneut auf dem Server gegen die führende Quelle; einen externen Kalender fragen Sie in diesem Moment ab, statt nur dem letzten Abgleich zu vertrauen. Bei parallelen Anfragen genügt das allein nicht, deshalb folgt die Absicherung in der Datenbank.
Zeitfenster kurz reservieren
Wer eine Zeit auswählt, kann sie für einige Minuten vorläufig halten, während die Angaben eingetragen werden. Andere sehen die Zeit dann als belegt. Jede Reservierung braucht eine Ablaufzeit, danach wird die Zeit wieder frei. Zeigen Sie die Restzeit an und prüfen Sie beim Absenden, ob die Reservierung noch gilt. Zu lange Haltezeiten blockieren freie Termine.
Überschneidungen in der Datenbank ausschließen
Die verlässlichste Stelle für die letzte Prüfung ist die Datenbank. PostgreSQL kennt Datentypen für Zeiträume, etwa tstzrange für Zeitstempel mit Zeitzone, und Ausschlussbedingungen
Quelle 5
. Eine solche Bedingung verhindert, dass zwei Einträge mit überlappenden Zeiträumen gleichzeitig in der Tabelle stehen, und weist einen überlappenden Eintrag mit einer Fehlermeldung ab
Quelle 5
. Mit der Erweiterung btree_gist lässt sich die Regel auf dieselbe Ressource beschränken, in der Dokumentation auf denselben Raum
Quelle 5
. Im Betrieb ist das etwa eine Mitarbeiterin, ein Stuhl im Salon oder ein Montageplatz.
Legen Sie Zeiträume so an, dass der Beginn dazugehört und das Ende nicht; PostgreSQL schreibt das als [ und )
Quelle 5
. Dann überschneiden sich Termine bis 10:00 Uhr und ab 10:00 Uhr nicht. Stornierte Termine und abgelaufene Reservierungen dürfen die Regel nicht auslösen, das muss die Umsetzung vorsehen. Bei Einsätzen vor Ort gehört die Anfahrt zum belegten Zeitraum, wie der Ratgeber zu Fahrzeiten in der Online-Terminbuchung zeigt. Die interaktive Demo rechnet das an einem Beispieltag vor.
Alternativ kann die Buchung in der Isolationsstufe „Serializable“ laufen. Dann muss die Anwendung Serialisierungsfehler abfangen und den Vorgang wiederholen Quelle 1 .
Wiederholte Übermittlungen erkennen
Anfragen mit nicht idempotenten Methoden wie POST soll ein Client laut HTTP-Standard nicht automatisch wiederholen, es sei denn, er weiß, dass die Anfrage tatsächlich idempotent ist, oder kann erkennen, dass die ursprüngliche Anfrage nie verarbeitet wurde Quelle 6 . Auslösen können Nutzer eine Wiederholung trotzdem, etwa durch Doppelklick oder Neuladen. Sichern Sie die Buchung deshalb auf dem Server ab: Das Formular erhält beim Öffnen eine eindeutige Vorgangskennung. Trifft sie erneut ein, antwortet der Server mit dem Ergebnis des ersten Versuchs, statt einen zweiten Termin anzulegen. Das Prinzip heißt Idempotenz. Ein gesperrter Button ergänzt diese Erkennung, ersetzt sie aber nicht.
Erst speichern, dann bestätigen
Die Zusage folgt erst, wenn die Datenbank den Termin angenommen hat. Bestätigungs-E-Mail und Kalendereintrag hängen an diesem Ergebnis, nicht am Klick. Scheitert nur der Kalendereintrag, bleibt die Buchung gültig: Das System wiederholt den Eintrag ohne Dublette und informiert das Team, falls das misslingt. Was eine gute Bestätigung enthält, zeigt der Beitrag zu Terminerinnerungen gegen No-Shows.
Kalenderänderungen zeitnah übernehmen
Trägt jemand direkt im Kalender einen Termin oder Blocker ein, muss die Website davon erfahren. Die Google Calendar API meldet Änderungen per Push-Benachrichtigung an eine HTTPS-Adresse, also per Webhook; die Nachricht selbst enthält keine Einzelheiten Quelle 2 . Ihr System holt die Änderungen danach per inkrementeller Synchronisation ab. Sie liefert alle Änderungen seit dem letzten Abgleich, gelöschte Einträge eingeschlossen Quelle 7 .
Google rechnet damit, dass ein kleiner Teil der Benachrichtigungen verloren geht; zudem laufen Benachrichtigungskanäle ab und müssen rechtzeitig ersetzt werden Quelle 2 . Ein regelmäßiger Abgleich im Hintergrund fängt beides auf. Erklärt der Dienst den gespeicherten Synchronisationsstand für ungültig, antwortet er mit dem Status 410; dann folgt ein vollständiger Neuabgleich Quelle 7 .
Zeitpunkte mit Zeitzone speichern
In Deutschland wird die Uhr am letzten Sonntag im März von 2 auf 3 Uhr vorgestellt; am letzten Sonntag im Oktober erscheint die Stunde von 2 bis 3 Uhr zweimal Quelle 3 . „2:30 Uhr“ ohne Versatz beschreibt in diesen Nächten keinen oder zwei Zeitpunkte. PostgreSQL weist solche Angaben nicht zurück, sondern wählt den UTC-Versatz nach einer festen Regel; er lässt sich aber ausdrücklich angeben Quelle 8 . Speichern Sie Termine deshalb als Zeitpunkt mit Zeitzone oder Versatz, und pflegen Sie Öffnungszeiten weiter in Ortszeit. Bei Videoterminen mit Kundschaft in anderen Zeitzonen nennt die Bestätigung die Zeitzone.
Ursachen und Maßnahmen im Überblick
| Ursache | Maßnahme | So prüfen Sie es |
|---|---|---|
| Gleichzeitige Anfragen | Datenbankregel gegen Überschneidungen | Mit zwei Geräten dieselbe Zeit gleichzeitig buchen |
| Prüfung nur beim Anzeigen | Erneute Prüfung beim Speichern | Zeit im zweiten Fenster buchen, dann im ersten absenden |
| Verzögerter Kalenderabgleich | Benachrichtigung, Abgleich und Abfrage vor der Zusage | Blocker im Kalender setzen und direkt danach online buchen |
| Mehrere Kanäle | Eine führende Quelle für alle Kanäle | Telefontermin erfassen und das Angebot der Website prüfen |
| Wiederholte Übermittlung | Vorgangskennung je Buchung | Doppelklick, Neuladen und Verbindungsabbruch beim Absenden |
| Manuelle Einträge | Interne Eingabe mit derselben Prüfung | Überschneidenden Termin intern eintragen |
| Zeitumstellung | Zeitpunkte mit Zeitzone speichern | Termin in der Umstellungsnacht anlegen und Anzeigen vergleichen |
Beispiel: Zwei Buchungen im selben Moment
Das Beispiel ist frei erfunden. Eine Fahrradwerkstatt bietet samstags Inspektionstermine online an. Buchungen landen zuerst in einer Datenbank mit Überschneidungsregel, danach im Werkstattkalender.
- Kundin A und Kunde B sehen Samstag, 10:00 Uhr, als frei und senden fast gleichzeitig ab.
- Der Server prüft beide Anfragen erneut. Noch ist keine gespeichert, beide Prüfungen melden „frei“.
- Die Datenbank nimmt die Buchung an, die zuerst gespeichert wird, hier die von Kundin A. Die zweite weist sie wegen der Überschneidung ab.
- Nur Kundin A erhält Kalendereintrag und Bestätigung.
- Kunde B sieht: „Diese Zeit wurde gerade vergeben. Ihre Angaben bleiben erhalten. Bitte wählen Sie eine der folgenden Zeiten.“ Darunter stehen die nächsten freien Termine.
- Er bucht 10:45 Uhr. Um 10:00 Uhr steht genau ein Termin im Kalender, der abgewiesene Versuch ist protokolliert.
Mit vorläufigen Reservierungen hätte Kunde B die Zeit meist schon bei der Auswahl als belegt gesehen.
Testfälle vor dem Start
Spielen Sie diese Fälle vor dem Start und nach größeren Änderungen durch, am besten mit zwei Personen und zwei Geräten:
| Fall | Erwartetes Verhalten |
|---|---|
| Zwei gleichzeitige Buchungen derselben Zeit | Genau eine Buchung wird gespeichert und bestätigt. Die zweite Person sieht einen Hinweis mit Alternativen, ihre Eingaben bleiben erhalten. |
| Doppelklick auf „Buchen“ | Es entstehen ein Termin und eine Bestätigung. Neuladen oder erneutes Absenden zeigt denselben Stand. |
| Eintrag direkt im Kalender | Die Zeit wird nach dem Abgleich nicht mehr angeboten. Wer sie noch im offenen Formular gewählt hat, erhält beim Absenden einen Hinweis statt einer Zusage. |
| Kalenderverbindung unterbrochen | Ungeprüfte Buchungen werden nach vereinbarter Regel zurückgestellt oder abgelehnt, das Team wird informiert. Nach der Wiederverbindung gleicht das System zuerst alle Änderungen ab. |
| Termin in der Nacht der Zeitumstellung | Im März wird keine Uhrzeit zwischen 2 und 3 Uhr angeboten. Im Oktober werden Termine in der doppelten Stunde eindeutig gespeichert; Kalender, Bestätigung und Erinnerung zeigen denselben Zeitpunkt. |
| Reservierung läuft ab | Die Zeit ist wieder buchbar. Wer später absendet, wird erneut geprüft. |
| Benachrichtigung vom Kalender bleibt aus | Der regelmäßige Abgleich findet die Änderung trotzdem. |
Wenn es trotzdem zu einer Überschneidung kommt
Solange Termine auch außerhalb der Website eingetragen werden, bleibt eine Restlücke: Kalendereintrag und Online-Buchung können fast gleichzeitig entstehen, bevor der Abgleich sie zusammenführt. Legen Sie deshalb vorab fest:
- Benachrichtigen: Das System meldet eine erkannte Überschneidung umgehend einer festgelegten Person, mit beiden Terminen und Kanälen. Es sagt nichts selbstständig ab.
- Persönlich klären: Die Person entscheidet nach vereinbarter Regel, etwa „die früher bestätigte Buchung bleibt“, und prüft Alternativen wie eine andere Mitarbeiterin oder eine Zeit kurz davor oder danach.
- Freundlich informieren: Die betroffene Person erfährt davon rechtzeitig, am besten telefonisch, sonst per Nachricht mit Entschuldigung und konkreten Alternativen.
- Ursache festhalten: Aus Kanal und Lücke entsteht eine neue Regel oder ein weiterer Testfall.
Eine Nachricht kann so lauten (frei erfunden):
Guten Tag, für Ihren Termin am Samstag um 10:00 Uhr ist bei uns eine Doppelbelegung entstanden. Das tut uns leid. Wir können Ihnen 10:45 Uhr oder Montag um 9:00 Uhr anbieten. Antworten Sie einfach auf diese Nachricht oder rufen Sie uns an.
Typische Fehler
- Nur im Browser prüfen: Das lässt sich umgehen und übersieht parallele Buchungen.
- Bestätigen vor dem Speichern: Die E-Mail sagt womöglich einen Termin zu, der gar nicht gespeichert wurde.
- Nur den Button sperren: Neuladen und Verbindungsabbrüche erzeugen trotzdem doppelte Übermittlungen.
- Reservierungen ohne Ablaufzeit: Abgebrochene Buchungen blockieren freie Zeiten. Dasselbe gilt für stornierte Termine, die die Überschneidungsregel weiter zählt.
- Telefontermine in einer eigenen Liste: Die Website kennt sie nicht.
- Nur auf Benachrichtigungen verlassen: Eine verlorene Benachrichtigung bleibt ohne regelmäßigen Abgleich unbemerkt.
- Konflikte stillschweigend lösen: Wer einen Termin automatisch löscht, riskiert, dass jemand vergeblich vor der Tür steht.
Wenn Sie Unterstützung möchten
Akuma Digital richtet Online-Terminbuchungen für Websites ein. Vorab klären wir, wo Termine verbindlich gepflegt werden, welche Kanäle es gibt, ob Ihr Kalender angebunden werden kann und welche Fälle persönlich bleiben. Die Testfälle oben eignen sich als gemeinsame Abnahmeliste. Wie wir vorgehen, beschreibt die Seite Online-Terminbuchung für Ihre Website einrichten lassen.
Häufige Fragen
Reicht es, den Buchen-Button nach dem ersten Klick zu sperren?
Nein. Das hilft gegen versehentliche Doppelklicks, aber nicht gegen neu geladene Seiten, abgebrochene Verbindungen oder zwei Personen, die gleichzeitig buchen. Entscheidend sind die Prüfung auf dem Server, eine eindeutige Vorgangskennung je Buchung und eine Regel in der Datenbank, die überlappende Termine abweist.
Können Mitarbeiter weiterhin direkt im Kalender Termine eintragen?
Ja, wenn die Website diese Einträge berücksichtigt: Sie prüft den Kalender vor jeder Zusage und gleicht Änderungen regelmäßig ab. Weil ein Kalendereintrag und eine Online-Buchung fast gleichzeitig entstehen können, bleibt eine kleine Lücke. Dafür braucht es eine Benachrichtigung und einen festen Klärungsweg.
Wie lange sollte ein Zeitfenster während der Eingabe reserviert bleiben?
Das hängt vom Formular ab. Die Haltezeit sollte reichen, um die Angaben in Ruhe einzutragen, und kurz genug sein, damit abgebrochene Buchungen andere nicht lange blockieren. Zeigen Sie die verbleibende Zeit an und prüfen Sie beim Absenden, ob die Reservierung noch gilt.
Was sieht eine Kundin, wenn ihr Wunschtermin gerade vergeben wurde?
Sie erhält keine Bestätigung, sondern einen klaren Hinweis, dass die Zeit soeben vergeben wurde. Ihre Eingaben bleiben erhalten, und die nächsten freien Zeiten stehen direkt darunter. So kann sie ohne Neustart einen anderen Termin wählen.
Warum sollte ein Betrieb, der nachts geschlossen hat, die Zeitumstellung testen?
Der Test zeigt, ob das System Zeitpunkte eindeutig mit Zeitzone speichert. Fehlt diese Angabe, können sich auch Termine am Tag, Erinnerungen oder wiederkehrende Sperren rund um die Umstellung verschieben. Legen Sie testweise einen Eintrag in die Umstellungsnacht und prüfen Sie zusätzlich den ersten Termin am Morgen danach.
Quellen und weiterführende Informationen
- PostgreSQL-Dokumentation: Transaction Isolation
- Google Calendar API: Push notifications
- Sommerzeitverordnung (SoZV), § 2
- Google Calendar API: Freebusy – query
- PostgreSQL-Dokumentation: Range Types (Constraints on Ranges)
- IETF RFC 9110: HTTP Semantics, Abschnitt 9.2.2 Idempotent Methods
- Google Calendar API: Synchronize resources efficiently
- PostgreSQL-Dokumentation: Handling of Invalid or Ambiguous Timestamps