Ich bin in meiner Anwendung zwischen einer Update- und einer Insert-Abfrage auf einen Deadlock gestoßen, und ich kann nicht verstehen, warum Sperren auf eine Weise gegeben werden, die Deadlock verursacht.
Umgebung -
Abfragen - Nach zwei Abfragen (Abfragen werden abgeschnitten, um nur relevante Spalten anzuzeigen) -
Aktualisieren -
UPDATE 'MSC' SET 'm_id' = 110, 's_id' = 1234, 'c_id' = '9b39cd', WHERE 'MSC'.'id' = 54362
Einfügen -
INSERT INTO 'MSC' ('m_id', 's_id', 'c_id') VALUES (110, 1235, '9b39cd')
Deadlock -
SHOW ENGINE INNODB STATUS\G;
zeigt an, dass die Abfrage zuvor eingefügt wurde. %Vor%
Fragen - Ich bin nicht in der Lage, die folgenden zu verstehen 1. Warum musste die Aktualisierungsabfrage warten und konnte die Sperren nicht erhalten, wenn die Abfrage eingab? 2. Warum benötigt die Aktualisierungsabfrage eine exklusive (X) Sperre für die M-Tabelle / nimmt sie an.
Bitte teilen Sie Ihre Gedanken hier. Lassen Sie mich wissen, wenn zusätzliche Informationen erforderlich sind.
Besteht der ID-Wert von 110 in der M-Tabelle? Es kann auch nützlich sein, diese einzelnen Transaktionen in die Befehle START TRANSACTION;
und COMMIT;
einzubinden, um sicherzustellen, dass die Einfügung abgeschlossen ist, bevor das Update ausgeführt werden soll.
Beispiel:
%Vor% Wie bereits erwähnt, können Ihre beiden Abfragen keinen Deadlock verursachen. Aber mögliche nächste Situation. Zum Beispiel haben wir die nächsten Datensätze in MSC
table:
Nun versuchen wir, die nächsten Abfragen parallel auszuführen (ich habe Ihr Update geändert und 1235 anstelle von 1234 geschrieben):
%Vor% Wir müssen ein Problem mit dem eindeutigen Index auf ( m_id
, s_id
, c_id
) haben.
Aktualisieren und Einfügen können parallel beginnen, da vor Beginn der Ausführung kein Problem mit der Einschränkung besteht. Aber Abfragen können nicht beendet werden, da sie beide gleiche Zeilen erzeugen müssen und mit einer eindeutigen Einschränkung in Konflikt stehen müssen.
Um diese Situation zu vermeiden, können Sie erzwungene Sperren verwenden. Zum Beispiel
%Vor%Ich mag keine ähnlichen Schlösser, weil nach diesem Problem hier gelöst werden kann, aber in up-Ebene bewegt. Wenn es möglich ist, überarbeiten Sie Ihr Datenbankschema oder Ihren Algorithmus. Vielleicht finden Sie mehr Eleganz Weg, um Ihre Daten ohne Wahrscheinlichkeit von Deadlocks zu speichern und zu aktualisieren.