3 Stimmen

Verhindern von Wettlaufbedingungen für E-Commerce-Anwendung mit MySQL

Ich baue eine E-Commerce-Anwendung mit MySQL, aber ich habe Schwierigkeiten, eine Lösung zu finden, die das folgende Wettlaufproblem verhindert:

Zwei Benutzer zahlen gleichzeitig mit demselben Artikel im Warenkorb aus. Der Laden hat nur einen Artikel zum Verkauf verfügbar. Ein Benutzer sollte in der Lage sein, den letzten Artikel zu kaufen, und der andere Benutzer sollte eine Fehlermeldung sehen, weil der Artikel ausverkauft ist.

Ich verwende einen Artikelzähler, um die Anzahl der Artikel im Inventar zu verfolgen, daher dachte ich, ich würde den Artikel nach der Bearbeitung der Kreditkarte des Benutzers einfach verringern.

Ich kenne die SELECT...UPDATE-Abfrage in MySQL, aber ich würde gerne von Sperren von Zeilen oder Tabellen absehen - es sei denn, das ist wirklich der beste Weg für eine E-Commerce-App, dieses Problem zu lösen.

Ich bin auch daran interessiert, andere Lösungen zu hören, außer dem Überprüfen/Verringern eines Artikelzählers.

0 Stimmen

Re: "Lösungen außer ... Artikelzähler" siehe den Inventarabschnitt auf kylebanker.com/blog/2010/04/30/mongodb-and-ecommerce. Ich weiß, dass es Mongo verwendet, aber die Idee könnte auch in MySQL verwendet werden. z.B. Es gibt eine inventory-Tabelle, in der jede Option einen Eintrag hat. Dies ist mit einem Benutzer/Sitzung_ID verknüpft und hat einen Status: verfügbar, im Warenkorb und verkauft. Kontra: Ihre inventory-Tabelle wird ziemlich groß.

0voto

Zimbabao Punkte 8054

Warum machen Sie sich Sorgen um das Sperren? Es wird Ihnen nichts ausmachen, solange Sie nicht hunderte gleichzeitige Kunden haben und Datenbank-Engines wie InnoDB dafür gemacht sind, mit solchen Dingen umzugehen. Sie werden nicht um eine gewisse Art von Atomicity und Workaround herumkommen.

Sie müssen das Transaktionsmanagement auf Anwendungsebene beibehalten.

   Kasse 
   Artikel im Warenkorb reservieren
   if(Reservierung erfolgreich){
     Zahlung über Zahlungsschnittstelle durchführen
     if(Zahlung erfolgreich) {
        Reservierte Artikel auf den Status "verkauft" aktualisieren   
     }else{
         Reservierten Artikel wieder verfügbar machen.      
     }
   }else{
      Fehler anzeigen, dass der Artikel nicht verfügbar ist.
   }

Ein weiterer guter Weg, damit umzugehen, ist es, dass es nie zu einem "Fehler anzeigen, dass der Artikel nicht verfügbar ist" kommt. Ergänzen Sie den Bestand rechtzeitig, wenn er knapp wird.

0 Stimmen

Vielen Dank für den Tipp! Ich frage mich, wann und wie Sperren die Leistung beeinträchtigen können. Haben Sie zufällig Beispiele?

0 Stimmen

Wenn Sie einen Konflikt haben (viele Threads warten auf dasselbe Schloss), wird dies die Leistung beeinträchtigen. In der Regel ist es in MySQL kein großes Problem, wenn Sie ein Engine verwenden, das eine Sperrung auf Zeilenebene unterstützt (wie InnoDB), es sei denn, es warten viele Threads darauf, dieselbe Zeile gleichzeitig zu schreiben.

0voto

williamli Punkte 3540

Die Art und Weise, wie ich dabei vorgehe, ist 1. Verfügbarkeit für X Bücher überprüfen 2. Wenn es X Bücher gibt, die tatsächliche Bestellung aufgeben 3. die Verfügbarkeit erneut überprüfen: Wenn die Verfügbarkeit in Ordnung ist, dann ist alles in Ordnung... wenn die Verfügbarkeit nicht in Ordnung ist, storniere ich die Bestellung und benachrichtige den Kunden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X