MySQL verwendet SELECT … FOR UPDATE zur Bestätigung vor dem Schreiben der Transaktion
Am Beispiel von MySQLs InnoDB ist die Standardisolationsstufe von Tansaction REPEATABLE READ. Es gibt zwei Haupttypen von Lesesperren in der SELECT-Methode:
SELECT … LOCK IN SHARE MODE SELECT … FOR UPDATE
Diese beiden Methoden müssen auf die Übermittlung anderer Transaktionsdaten warten (Commit), bevor sie ausgeführt werden, wenn eine SELECT-Operation für dieselbe Datentabelle ausgeführt wird. Der Hauptunterschied besteht darin, dass LOCK IN SHARE MODE leicht zu einem Deadlock führen kann, wenn eine Partei dasselbe Formular aktualisieren möchte.
Um es einfach auszudrücken: Wenn Sie dasselbe Formular nach SELECT AKTUALISIEREN möchten, verwenden Sie am besten SELECT ... UPDATE.
Zum Beispiel: Angenommen, es gibt eine Menge in der Produktform „Produkte“, um die Menge des Produkts zu speichern. Bevor die Bestellung erstellt wird, muss festgestellt werden, ob die Menge des Produkts ausreicht (Menge>0). , und dann wird die Menge auf 1 aktualisiert.
Unsichere Praktiken:
1 SELECT quantity FROM products WHERE id=3; 1 UPDATE products SET quantity = 1 WHERE id=3;
Warum ist es unsicher?
In einigen wenigen Fällen kann es kein Problem geben, aber beim Zugriff auf große Datenmengen wird es auf jeden Fall Probleme geben.
Wenn wir den Lagerbestand abziehen müssen, wenn die Menge> 0 ist, gehen wir davon aus, dass die vom Programm in der ersten SELECT-Zeile gelesene Menge 2 ist. Es scheint, dass die Zahl korrekt ist, aber wenn MySQL sich auf das UPDATE vorbereitet, hat jemand jemanden Möglicherweise wurde der Bestand auf 0 abgezogen, aber das Programm wusste es nicht und führte das falsche UPDATE durch.
Daher muss ein Transaktionsmechanismus verwendet werden, um sicherzustellen, dass die gelesenen und übermittelten Daten korrekt sind.
Damit wir es in MySQL so testen können: (Hinweis 1)
1 SET AUTOCOMMIT=0; 2 BEGIN WORK; 3 SELECT quantity FROM products WHERE id=3 FOR UPDATE;
Zu diesem Zeitpunkt sind die Daten mit der ID=3 im Produktdaten sind gesperrt (Hinweis 3) Andere Transaktionen müssen warten, bis diese Transaktion festgeschrieben wird, bevor sie ausgeführt werden. SELECT * FROM products WHERE id=3 FOR UPDATE (Hinweis 2) Dadurch wird sichergestellt, dass die in anderen Transaktionen nach Menge gelesene Anzahl korrekt ist.
1 UPDATE products SET quantity = '1' WHERE id=3 ; 2 COMMIT WORK;
Commit wird in die Datenbank geschrieben und Produkte werden entsperrt.
Hinweis 1: BEGIN/COMMIT ist der Start- und Endpunkt der Transaktion. Sie können mehr als zwei MySQL-Befehlsfenster verwenden, um den Sperrstatus interaktiv zu beobachten.
Hinweis 2: Während einer Transaktion wird nur SELECT... FOR UPDATE oder LOCK IN SHARE MODE für die gleichen Daten auf den Abschluss anderer Transaktionen warten, bevor SELECT... ausgeführt wird dadurch.
Hinweis 3: Da InnoDB standardmäßig die Sperre auf Zeilenebene verwendet, lesen Sie bitte diesen Artikel zum Sperren von Datenspalten.
Hinweis 4: Versuchen Sie, die LOCK TABLES-Anweisung nicht in InnoDB-Formularen zu verwenden. Wenn Sie sie als letzten Ausweg verwenden müssen, lesen Sie bitte die offiziellen Anweisungen zur Verwendung von LOCK TABLES in InnoDB, um häufige Deadlocks im System zu vermeiden .
Das Obige ist der Inhalt der MySQL-Transaktionsverarbeitung mit hoher Parallelität. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!