Heim  >  Artikel  >  Backend-Entwicklung  >  Gleichzeitige Schreibvorgänge in MySQL und GORM verursachen Fehler

Gleichzeitige Schreibvorgänge in MySQL und GORM verursachen Fehler

WBOY
WBOYnach vorne
2024-02-09 10:30:18487Durchsuche

Gleichzeitige Schreibvorgänge in MySQL und GORM verursachen Fehler

Das Problem des gleichzeitigen Schreibens zwischen MySQL und GORM bereitet Entwicklern schon immer Kopfzerbrechen. In Situationen mit hoher Parallelität kann das gleichzeitige Schreiben mehrerer Threads in die Datenbank zu Dateninkonsistenzen oder fehlerhaften Ergebnissen führen. Der PHP-Editor Baicao analysiert für Sie die Ursachen und Lösungen dieses Problems, um Ihnen dabei zu helfen, die durch gleichzeitiges Schreiben verursachten Probleme zu vermeiden. Durch angemessenes Design und Optimierung kann das Problem des gleichzeitigen Schreibens von MySQL und GORM effektiv gelöst werden, um Datenkonsistenz und -genauigkeit sicherzustellen.

Frageninhalt

Ich habe ein komplexes CSV-Importskript in Golang implementiert. Ich verwende die Workerpool-Implementierung. In diesem Worker-Pool führen Worker 1.000 kleine CSV-Dateien aus, die Produkte kategorisieren, kennzeichnen und kennzeichnen. Sie schreiben alle in dieselbe Datenbanktabelle. So weit, ist es gut.

Das Problem, mit dem ich konfrontiert bin, besteht darin, dass der Prozess zufällig mit der folgenden Meldung abstürzt, wenn ich mehr als 2 Arbeiter auswähle

Der Arbeitsablauf ist

foreach (csv) {
 workerPool.submit(csv)
}

func worker(csv) {
 foreach (line) {
   import(line)
 }
}

import(line) {
 product = get(line)
 product.category = determine_category(product)
 product.brand = determine_brand(product)
 save(brand)
 product.tags = determine_tags(product)
 //and after all
 save(product)
}

Ich habe versucht, den save()-Aufruf in eine Transaktion einzubinden, aber es hat nicht geholfen.

Jetzt habe ich folgende Fragen:

  1. Ist MySQL zum gleichzeitigen Speichern auf einer Tabelle geeignet?
  2. Wenn eine Transaktion erforderlich ist, um diese Aufgabe zu erfüllen, wo sollte sie festgelegt werden?
  3. Ist der Go-SQL-Treiber (der Fehler tritt immer in packet.go:1102 auf) dafür geeignet?
  4. Kann mir jemand helfen (vielleicht ein paar Stunden engagieren)?

Ich stecke völlig fest. Ich kann auch den Quellcode teilen, wenn es hilft. Aber zuerst möchte ich wissen, ob Sie vermuten, dass dies mein Code oder ein allgemeines Problem ist.

Workaround

Öffnen Sie in jeder Goroutine (oder Thread, für Sprachen, die Threads verwenden) eine neue Datenbankverbindung.

Das MySQL-Protokoll ist zustandsbehaftet, was bedeutet, dass Anfragen und Antworten sehr verwirrend werden können, wenn mehrere Goroutinen versuchen, dieselbe Verbindung zu verwenden.

Das gleiche Problem tritt auch auf, wenn Sie versuchen, eine andere Art von Stateful-Protokoll-Verbindung zwischen Goroutinen zu teilen.

Zum Beispiel ist FTP auch ein zustandsbehaftetes Protokoll, das möglicherweise leichter zu verstehen ist. Die Client-Goroutine sendet möglicherweise eine Nachricht wie „Datei x abrufen“ und die Antwort sollte eine Reihe von Nachrichten sein, die den Inhalt der Datei enthalten. Wenn eine andere Goroutine versucht, dieselbe Verbindung zu verwenden, während die Anfrage/Antwort ausgeführt wird, geraten beide Clients durcheinander. Die zweite Goroutine liest Pakete, die zu einer Datei gehören, die sie nicht angefordert hat. Die erste Goroutine, die die Datei anfordert, stellt fest, dass einige der erwarteten Pakete gelesen wurden.

Ebenso unterstützt das MySQL-Protokoll nicht mehrere Client-Goroutinen, die sich eine einzige Verbindung teilen.

Das obige ist der detaillierte Inhalt vonGleichzeitige Schreibvorgänge in MySQL und GORM verursachen Fehler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen