Mit Django auf eine MySQL-Datenbank, die ich die folgende Fehlermeldung erhalten:Vermeidung von Deadlock MySQL in Django ORM
OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')
Der Fehler in dem folgenden Code steigt:
start_time = 1422086855
end_time = 1422088657
self.model.objects.filter(
user=self.user,
timestamp__gte=start_time,
timestamp__lte=end_time).delete()
for sample in samples:
o = self.model(user=self.user)
o.timestamp = sample.timestamp
...
o.save()
Ich habe mehrere parallell Prozesse arbeiten die gleiche Datenbank und manchmal haben sie möglicherweise den gleichen Job oder eine Überlappung in Beispieldaten. Deshalb muss ich die Datenbank löschen und dann die neuen Samples speichern, da ich keine Duplikate haben möchte.
Ich führe die ganze Sache in einem Transaktionsblock with transaction.commit_on_success()
und bekomme oft die OperationalError
Ausnahme. Was ich bevorzuge, ist, dass die Transaktion nicht in einem Deadlock endet, sondern nur sperrt und darauf wartet, dass der andere Prozess mit seiner Arbeit beendet wird.
Von dem, was ich gelesen habe, sollte ich die Schlösser richtig bestellen, aber ich bin mir nicht sicher, wie man das in Django macht.
Was ist der einfachste Weg um sicherzustellen, dass ich diesen Fehler nicht bekomme und trotzdem sicherstelle, dass ich keine Daten verliere?
Ich habe gerade 'select_for_update()' (und '__range') ausprobiert, aber ich sehe immer noch Deadlocks. N.b. 'samples' kommt nicht von der db, sondern von der eigentlichen Verarbeitung. Die Datenbank wird nur verwendet, um einige der Informationen zu speichern, die von einem viel größeren Datensatz gesammelt wurden. – gurglet
Ich habe die Antwort aktualisiert. – catavaran