2017-07-26 5 views
1

Also erstelle ich ein Angebot (Schätzung) Generierungsmodul in meinem Online-Shop.MySQL erhöhen und vermeiden falsche Referenzierung

Nun, ich habe eine erstellt, aber ich möchte Beratung auf etwas bekommen, stört mich.

Die Angebotserstellung erfolgt durch einen Kunden Produkte in ihren Einkaufswagen, und dann ein PDF-Angebot statt Check-out mit den Produkten zu generieren entscheiden.

Die Zitat-Nummer (Belegnummer) wird in der Datenbank gespeichert ist, und das gibt natürlich jedes eine eindeutige Referenznummer zitieren, aus offensichtlichen Gründen.

Jetzt sobald ein erfolgreicher Versuch, ein Angebot erfolgt, der folgende Code zieht die aktuellen Referenznummer, erhöht er dich um 1, zu erzeugen und dann aktualisiert den Datenbankeintrag mit den neu Referenznummer erhöht:

$wbquery = "select wq.configuration_key, wq.configuration_value from " . TABLE_CONFIGURATION . " wq where wq.configuration_key='" . $wbkey . "'"; 
$wbadd = $db->Execute($wbquery); 

$newwb = $wbadd->fields['configuration_value'] + 1; 

$wbdone = "update " . TABLE_CONFIGURATION . " set configuration_value = '" . $db->prepare_input(trim($newwb)) . "' where configuration_key = '" . $wbkey . "'"; 
$db->Execute($wbdone); 

$docno = $qtype.date('y').sprintf('%05d', $newwb); 

bof TLDR;

Hier erhalten wir die aktuell gespeicherte Referenznummer und fügen dann 1 hinzu. Dann aktualisieren wir die Referenznummer in der Datenbank mit diesem Wert.

Wir weisen der Variablen $ docno auch die Referenznummer zu, weil wir sie in die PDF-Datei drucken. Neben der Referenznummer fügen wir ein Präfix, $ qtype (bestehend aus 2 Buchstaben), hinzu Datum ('y'), das eine 2-stellige Darstellung des aktuellen Jahres ist. Wir erzwingen auch, dass die Referenznummer Nullen vor der Referenznummer hinzufügt, um sicherzustellen, dass sie mindestens 5 Ziffern lang ist.

eof TLDR;

Wie stelle ich sicher, dass, wenn durch irgendeine Maßnahme oder Ausdehnung der Phantasie, dass, wenn zwei Kunden passieren ein Angebot und genau die gleiche Zeit zu erzeugen, dass es keine leichter Konflikt.

Wenn Kunde A ein Angebot zur gleichen Zeit wie Kunde B generiert, gibt es eine Chance, dass der Versuch von Kunde A die aktuelle Referenznummer zieht, und der Versuch von Kunde B wird auch die gleiche Referenznummer ziehen und falsch teilen die gleiche Referenz?

Oder gibt es ein Off-Chance, dass die Aktualisierung der Datenbank wieder an der Reihe passieren könnte, und fälschlicherweise den Zuwachs tun?

Der Wert in der Datenbank in einer Spalte, die TEXT ist der Typ - und hat keine Autoinkrement-Eigenschaften.

Die Sache ist, ich erwarte nicht, dass dies jemals passieren wird, das Zitat-System wird sowohl von Kunden als auch von Admin-Personal verwendet werden - aber ich will nur sicherstellen, dass ... es nie passiert.

Irgendwelche Ratschläge? Vielen Dank.

P.S. - Ich habe eine Sicherheitsmaßnahme installiert, die einen zufälligen MD5-Hash zu dem Dateinamen hinzufügt, unter dem das PDF-Zitat gespeichert ist. Dadurch wird sichergestellt, dass ein Kunde, der ein Angebot erstellt, niemals versehentlich ein Angebot eines anderen Kunden erhält, wenn die Angebote dieselbe Referenznummer haben. Ursprünglich speicherte es das Zitat mit dem grundlegenden $ docno - aber ich erkannte, dass dies ein Datenschutzrisiko darstellen könnte, das ist, wenn ich den MD5 eindeutigen Hash dem Dateinamen hinzufügte.

+0

Denken Sie daran, dass Sie hier über zwei verschiedene Dinge sprechen. Eine davon ist die "öffentliche" ID, die oben in der PDF-Datei gedruckt wird und so für Ihren Kunden (und möglicherweise Ihren Rivalen) sichtbar ist. Die andere ist die interne Datenbank-ID (eine Komponente) des PRIMARY KEY - die keine direkte Beziehung zu der gedruckten ID haben muss. – Strawberry

Antwort

1

Sie fragen nach einem "Race Condition" (wenn Sie mehr Forschung betreiben wollen).

Durch den Klang der Dinge, möchten Sie nicht dies in Ihrem PHP erhöhen. Es wird Ihnen helfen, mysql dies mit seiner eigenen automatischen Inkrementierung zu tun.

Also meine Antwort/Beratung ist, Redesign Ihrer Tabellenstruktur, so dass Zitat-ID ist nicht TEXT und das ist AUTO_INCREMENT.

Sonst müssen Sie zu größeren Schwierigkeiten kommen, um gegen race Bedingungen zu schützen.

+1

Danke für den Ausdruck! Schließlich weiß, wie es heißt LOL! Ich fand das auf einer anderen stackoverflow Frage dank Ihnen: https://stackoverflow.com/questions/2364273/how-to-make-sure-there-is-no-race-condition-in-mysql-database-when-incrementing - Ist der zweite Vorschlag in der angenommenen Antwort nicht geeignet und verhindert auch die Notwendigkeit eines automatischen Inkrements? – StuyvesantBlue

+0

Okay, es stellt sich heraus, dass meine Datenbank MyISAM ist. Ich gehe also davon aus, dass die Transaktionsmethode nicht funktioniert. – StuyvesantBlue

Verwandte Themen