Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Stellt MySQL Abfragen in die Warteschlange?

ABFRAGEN LAUFEN NICHT IMMER PARALLEL AB

Das hängt von der Datenbank-Engine ab. Bei MyISAM erwirbt fast jede Abfrage eine Sperre auf Tabellenebene, was bedeutet, dass die Abfragen sequentiell als Warteschlange ausgeführt werden. Mit den meisten anderen Engines können sie parallel laufen.

echo_me sagt nothing happens at the exact same time and a CPU does not do everything at once

Das stimmt nicht ganz. Es ist möglich, dass ein DBMS auf einer Maschine mit mehr als einer CPU und mit mehr als einer Netzwerkschnittstelle läuft. Es ist sehr unwahrscheinlich, dass 2 Abfragen gleichzeitig eintreffen könnten - aber nicht unmöglich, daher gibt es einen Mutex, um sicherzustellen, dass der Paring/Ausführungs-Übergang nur als ein einziger Thread läuft (der Ausführung - nicht unbedingt der gleiche leichte Prozess).

Es gibt zwei Ansätze zur Lösung von gleichzeitigem DML - entweder die Verwendung von Transaktionen (bei denen jeder Benutzer effektiv einen Klon der Datenbank erhält) und wenn die Abfragen abgeschlossen sind, versucht das DBMS, alle Änderungen abzugleichen - wenn die Abstimmung fehlschlägt, setzt das DBMS eine davon zurück die Abfragen und meldet es als fehlgeschlagen. Der andere Ansatz ist die Verwendung von Sperren auf Zeilenebene - das DBMS identifiziert die Zeilen, die durch eine Abfrage aktualisiert werden, und markiert sie als für die Aktualisierung reserviert (andere Benutzer können die Originalversion jeder Zeile lesen, aber jeder Versuch, die Daten zu aktualisieren, wird gesperrt, bis die Zeile wieder verfügbar ist).

Ihr Problem ist, dass Sie zwei MySQL-Clients haben, von denen jeder die Tatsache abgerufen hat, dass noch ein Artikel auf Lager ist. Dies wird durch die Tatsache weiter verkompliziert, dass (da Sie PHP erwähnen) die Lagerbestände möglicherweise in einer anderen DBMS-Sitzung abgerufen wurden als die nachfolgende Lagerbestandsanpassung - Sie können keine Transaktion haben, die sich über mehr als eine HTTP-Anforderung erstreckt. Daher müssen Sie jeden Fakt, der außerhalb des DBMS gepflegt wird, innerhalb einer einzigen Transaktion revalidieren.

Optimistisches Sperren kann einen Pseudo-Transaktionskontrollmechanismus schaffen – Sie kennzeichnen einen Datensatz, den Sie ändern möchten, mit einem Zeitstempel und der Benutzerkennung (bei PHP ist die PHP-Sitzungs-ID eine gute Wahl) – wenn Sie ihn ändern möchten, etwas anderes geändert hat, weiß Ihr Code, dass die zuvor abgerufenen Daten ungültig sind. Dies kann jedoch zu weiteren Komplikationen führen.