Die Frage, die Sie sich zuerst stellen müssen, lautet: Welche Art von Problemszenario möchten Sie vermeiden?
- Der Benutzer klickt versehentlich (oder aus Frustration, ...) zweimal auf eine Schaltfläche.
- Eine Ressource, die nur einmal verfügbar ist (wie eine Reservierung für einen bestimmten Sitzplatz in einem Flugzeug), wird zweimal verbraucht.
Sagen Sie nicht einfach: "Ich möchte beides vermeiden". Selbst wenn Sie das tun, müssen Sie die beiden Probleme getrennt behandeln.
Problem 1
Dies ist besser auf der Client-Seite zu lösen (z. B. durch Deaktivierung der Schaltfläche, sobald sie angeklickt wird).
Es kann auch serverseitig gelöst werden (durch Überprüfung von Sequenznummern oder Token oder vielleicht des Hash-Codes des Inhalts, ...), aber ich sehe den Sinn nicht wirklich. Wenn der Benutzer wirklich zweimal abschicken will (z.B. indem er das JavaScript so manipuliert, dass die Schaltfläche nicht deaktiviert wird), dann lassen Sie ihn einfach: Bei Problem 1 geht es nicht um Sicherheit.
Problem 2
Dies muss (außer in sehr speziellen Situationen) auf der Serverseite gelöst werden. Es geht vor allem um die Sicherheit. Aber wenn Sie darüber nachdenken, dieses Problem kann nicht durch die Verhinderung der doppelten Einreichung gelöst werden ! Warum nicht?
Schauen wir uns unser Beispiel an: Ein Sitzplatz in einem Flugzeug darf nur einmal reserviert werden. Dagegen kann auf verschiedene Weise verstoßen werden:
- Durch Doppelvorlage.
- Durch denselben Benutzer, der zur gleichen Zeit z. B. von verschiedenen Browser-Fenstern aus einreicht.
- Wenn mehrere Benutzer gleichzeitig versuchen zu reservieren.
Die saubere Art, das Problem zu lösen, besteht darin, die Verfügbarkeit des Sitzplatzes direkt bei der Reservierung zu prüfen. Es spielt keine Rolle, ob ein Verstoß durch eine Doppelanmeldung verursacht wurde (versehentliche Doppelanmeldungen fallen unter Problem 1).
... und Problem 3
Wenn Sie einen Mechanismus zur automatischen Wiedervorlage implementiert haben, können Sie auch auf eine dritte Art von Problem stoßen:
Angenommen, der Benutzer möchte einen Artikel in seinen Einkaufswagen legen. Der Client sendet, erhält aber keine Antwort vom Server, bevor die Zeit abgelaufen ist. Er sendet also automatisch erneut. Der Server empfängt jedoch beide Nachrichten und versucht, beide zu verarbeiten, so dass er den Artikel zweimal in den Einkaufswagen legt.
Die beste Lösung, um dies zu vermeiden, besteht meiner Meinung nach darin, keine Aktionen wie "einen Artikel in den Warenkorb legen" zu verwenden, sondern "die Zielanzahl der Artikel auf 1 setzen". Auch hier könnte man mit Sequenznummern usw. arbeiten.