VorwortPessimistisches und optimistisches Sperren sind zwei Konzepte zur Lösung von Parallelitätsproblemen, die auf unterschiedlichen Plattformen jeweils ihre eigene Implementierung haben. Beispielsweise kann in Java synchronisiert als Implementierung einer pessimistischen Sperre betrachtet werden (nicht streng, es gibt einen Sperren-Upgradeprozess und es wird nur dann als Schwergewichtssperre betrachtet, wenn es auf eine Schwergewichtssperre aktualisiert wird), und die atomare Klasse Atomic*** kann als Implementierung einer optimistischen Sperre betrachtet werden. Pessimistische Sperre Es verfügt über starke exklusive und exklusive Eigenschaften und die Daten sind während des gesamten Verarbeitungsprozesses gesperrt, was im Allgemeinen durch den Mutex des Systems erreicht wird. Wenn andere Threads versuchen, die Sperre zu erhalten, werden sie blockiert, bis der Thread, der die Sperre hält, sie freigibt. Optimistisches Sperren Seien Sie optimistisch, was die Änderung und den Zugriff auf Daten angeht, und gehen Sie davon aus, dass keine Konflikte auftreten. Nur wenn Daten zur Aktualisierung übermittelt werden, werden sie auf Konflikte geprüft. Wenn kein Konflikt vorliegt, wird die Aktualisierung problemlos übermittelt. Andernfalls schlägt dies schnell fehl und gibt einen Fehler an den Benutzer zurück, sodass dieser entscheiden kann, was als Nächstes zu tun ist. Im Allgemeinen wird nach einem Fehler so lange weiter versucht, bis die Aktualisierung erfolgreich übermittelt wurde. MySQL selbst unterstützt den Sperrmechanismus. Wenn wir beispielsweise die Anforderung haben, „zuerst abzufragen und dann zu schreiben“, hoffen wir, dass der gesamte Prozess eine atomare Operation ist und nicht in der Mitte unterbrochen werden kann. Zu diesem Zeitpunkt können wir dies erreichen, indem wir der abgefragten Datenzeile eine „exklusive Sperre“ hinzufügen. Solange die aktuelle Transaktion die Sperre nicht freigibt, blockiert MySQL die Erlangung exklusiver Sperren durch andere Transaktionen, bis die aktuelle Transaktion die Sperre freigibt. Diese Art von exklusiver Sperre am unteren Ende von MySQL wird „pessimistische Sperre“ genannt. MySQL selbst bietet keine optimistische Sperrfunktion, Entwickler müssen diese selbst implementieren. Eine gängige Vorgehensweise besteht darin, der Tabelle eine Versionsspalte hinzuzufügen, um die Version der Datenzeile zu kennzeichnen. Wenn wir die Daten aktualisieren müssen, müssen wir die Version vergleichen. Wenn die Version konsistent ist, bedeutet dies, dass die Daten während dieses Zeitraums nicht durch andere Transaktionen geändert wurden. Andernfalls bedeutet dies, dass die Daten durch andere Transaktionen geändert wurden und ein erneuter Versuch erforderlich ist. Tatsächlicher KampfAngenommen, die Datenbank hat zwei Tabellen: die Produkttabelle und die Bestelltabelle. Nach der Bestellung müssen Benutzer zwei Vorgänge ausführen:
Ausgangsdaten: Das Produkt mit der ID 1 ist in einer Stückzahl von 100 auf Lager und die Daten in der Bestelltabelle sind leer. Der Client startet 10 Threads, um gleichzeitig Bestellungen aufzugeben. Wie verhalten sie sich in den Szenarien ohne Sperre, pessimistische und optimistische Sperre? Nachfolgend sehen Sie die SQL-Anweisung zum Erstellen einer Tabelle: -- Warentabelle CREATE TABLE `Waren` ( `id` bigint(20) NICHT NULL AUTO_INCREMENT, `goods_name` varchar(50) NICHT NULL, `Preis` Dezimalzahl (10,2) NICHT NULL, `stock` int(11) DEFAULT '0', `version` int(10) unsigned NOT NULL DEFAULT '0', PRIMÄRSCHLÜSSEL (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 -- Auftragstabelle CREATE TABLE `t_order` ( `id` bigint(20) NICHT NULL AUTO_INCREMENT, `goods_id` bigint(20) NICHT NULL, `order_time` datetime NICHT NULL, PRIMÄRSCHLÜSSEL (`id`) MIT BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 1. Kein SchlossEs werden keine Maßnahmen ergriffen. //Eine Bestellung aufgeben private boolean order(){ Waren Waren = WarenMapper.selectById(1L); Boolescher Erfolg = falsch; wenn (Ware.Bestand abrufen() > 0) { waren.Lagerbestand festlegen(waren.Lagerbestand abrufen() - 1); // Lagerbestand aktualisieren goodsMapper.updateById(goods); // Eine Bestellung erstellen orderMapper.save(goods.getId()); Erfolg = wahr; } Erfolg zurückgeben; } Die Konsolenausgabe lautet: 2. Pessimistische SperreFügen Sie beim Abfragen von Produkten FOR UPDATE hinzu und fügen Sie der Datenzeile eine exklusive Sperre hinzu. Auf diese Weise werden andere Threads bei erneuter Abfrage blockiert. Bis die Transaktion des aktuellen Threads festgeschrieben und die Sperre aufgehoben wird, können andere Threads weiterhin Bestellungen aufgeben. Die Parallelitätsleistung dieser Methode ist gering. SQL-Anweisung @Select("AUSWÄHLEN * VON waren WHERE id = #{id} FÜR UPDATE") Waren selectForUpdate(Lange ID); Die Konsolenausgabe lautet: Hinweis: Um wirksam zu sein, muss FOR UPDATE in einer Transaktion erfolgen und die Abfrage und die Aktualisierung müssen in derselben Transaktion erfolgen! ! ! 3. Optimistisches SperrenDie Implementierungsidee lautet: Überprüfen Sie bei jedem Update die Versionsnummer. Wenn die Versionsnummer konsistent ist, bedeutet dies, dass die Daten während des Zeitraums nicht von anderen Threads geändert wurden und der aktuelle Thread das Update normal übermitteln kann. Andernfalls bedeutet dies, dass die Daten von anderen Threads geändert wurden und der aktuelle Thread sich drehen und erneut versuchen muss, bis das Geschäft erfolgreich ist. Bei einer Datenaktualisierung muss die Versionsnummer hochgezählt werden! ! ! @Update("UPDATE Waren SET Bestand = #{Bestand},Version = Version+1 WO ID = #{ID} UND Version = #{Version}") int updateByVersion(Long-ID, Integer-Bestand, Integer-Version); Geschäftskodex Boolesche Reihenfolge () { Waren Waren = WarenMapper.selectById(1L); Boolescher Erfolg = falsch; wenn (Ware.Bestand abrufen() > 0) { waren.Lagerbestand festlegen(waren.Lagerbestand abrufen() - 1); // Inventar mit Versionsnummer aktualisieren int result = goodsMapper.updateByVersion(goods.getId(), goods.getStock(), goods.getVersion()); wenn (Ergebnis <= 0) { // Aktualisierung fehlgeschlagen, was darauf hinweist, dass die Daten während des Zeitraums von anderen Threads geändert wurden und ein rekursiver Wiederholungsversuch erforderlich ist return order(); } // Eine Bestellung erstellen orderMapper.save(goods.getId()); Erfolg = wahr; } Erfolg zurückgeben; } Die Konsolenausgabe lautet: ZusammenfassenDies ist das Ende dieses Artikels über MySQL-Lösungen für pessimistisches und optimistisches Sperren. Weitere relevante Inhalte zu MySQL-Lösungen für pessimistisches und optimistisches Sperren finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Grundlegende Verwendung des Befehls wget unter Linux
>>: Drei Möglichkeiten zur Implementierung des Wasserfall-Flow-Layouts
Finden Sie das Problem Als ich kürzlich die vorhe...
1. Laden Sie das Installationspaket von der offiz...
Heute hatte ich etwas Freizeit, um eine Website f...
Vorwort Die Rolle des Prozessmanagements: Integri...
1. Einführung in VMware vSphere VMware vSphere is...
In diesem Artikelbeispiel wird der spezifische Co...
MySql-Index Indexvorteile 1. Sie können die Einde...
Inhaltsverzeichnis 1. Langsame Abfragekonfigurati...
1. Ereignissprudeln : Wenn im Prozess der Ereigni...
Code kopieren Der Code lautet wie folgt: <html...
Codebeispiel Fügen Sie im Head-Tag eine Codezeile ...
Vorwort In einem früheren Projekt wurde die Sorti...
Seite: Basis: <Vorlage> <div Klasse=&quo...
Das Download- und Installationstutorial für MySQL...
Inhaltsverzeichnis Vorwort Szenarien für die Verw...