Wie man InnoDB Deadlocks in Java / JDBC richtig behandelt?

8

Ich arbeite hier auf einer theoretischen Basis, ich möchte sicherstellen, dass alle meine Basen abgedeckt sind.

Ich habe ziemlich viel in InnoDB mit Java gelesen und wie Deadlocks auftreten können, egal welche Frage Sie ausführen. Obwohl ich ziemlich gut mit der Theorie und den Best Practices vertraut bin, bin ich ziemlich ahnungslos, wie man den Catch-Mechanismus der Neuausgabe von Transaktionen implementiert, wenn ein Deadlock auftritt.

Gibt es bestimmte Ausnahmen, auf die man achten sollte? Wird die Ausnahme erst nach dem Aufruf von connection.commit() ausgelöst oder kann sie auftreten, sobald ich PreparedStatement ausgeführt habe? Sollten die Dinge in einer Schleife laufen mit einer Begrenzung wie oft die Schleife läuft?

Ich brauche im Grunde genommen nur ein Java-Codebeispiel, wie dieses Ding im Allgemeinen gehandhabt wird. Da ich mir nicht sicher bin, wo die Dinge eingreifen, z. B., instanziere ich PreparedStatement -Objekte neu oder schließe sie zuerst usw. usw., alles ist sehr verwirrend. Gleiches gilt für ResultSet -Objekte.

Bearbeiten: Ich sollte wahrscheinlich erwähnen, dass ich mit Transaktionen arbeite und auto commit auf 0 setze.

Edit 2: Bin ich mit diesem Pseudocode auf dem richtigen Weg? Ich habe keine Ahnung

%Vor%     
xLite 31.05.2013, 09:03
quelle

1 Antwort

12

Ihr Code ist im Wesentlichen korrekt. Die Ausnahme, die ausgelöst wird, wenn ein Deadlock auftritt, ist SQLException . Die getSQLState() -Methode der Ausnahme liefert einen Fehlercode, der zusätzlich bereitstellt Informationen über den tatsächlichen Fehler.

Sie sollten auch eine kurze Zeit zwischen den Versuchen warten, um Ihren Server nicht zu sehr zu belasten.

Wie Sie es sich erraten haben, legen Sie eine maximale Anzahl von Versuchen fest, oder Sie landen in einer Endlosschleife.

Der endgültige Code könnte so aussehen:

%Vor%

Offensichtlich ist der obige Code suboptimal. Sie können Fehler, die zur Verbindungszeit auftreten, und Fehler zur Ausführungszeit unterscheiden. Sie könnten auch feststellen, dass nach einigen Fehlern wenig Hoffnung besteht, dass ein anderer Versuch funktioniert (z. B. falsche Anmeldeinformationen oder SQL-Syntaxfehler).

Sie haben viele Fragen gestellt, aber ich werde versuchen, sie alle zu beantworten:

  

Gibt es bestimmte Ausnahmen, auf die man achten sollte?

Ja, siehe oben: SQLException 's sind diejenigen mit mehr Informationen, die von getErrorCode() oder getSQLState() bereitgestellt werden.

  

Wird die Ausnahme nur ausgelöst, nachdem ich connection.commit () aufgerufen habe?

Ein SQLException könnte von praktisch allen Methoden aller Klassen aus dem java.sql -Paket geworfen werden.

  

Sollen die Dinge in einer Schleife laufen, mit einer Grenze wie oft die Schleife läuft?

Ja, siehe oben.

  

Muss ich [muss] PreparedStatement Objekte erneut instanziieren?

Offensichtlich müssen Sie keine PreparedStatement zwischen zwei Abfragen neu erstellen. Sie müssen nur neue Werte für Ihre Parameter festlegen, bevor Sie executeQuery() erneut aufrufen. Wenn Sie eine weitere Abfrage ausführen müssen, ist natürlich ein neues PreparedStatement erforderlich.

  

Gleiches gilt auch für ResultSet Objekte

Ein (neues) Objekt ResultSet wird von Statement.executeQuery() zurückgegeben, das das Ergebnis der Abfrage darstellt. Du erstellst niemals ein solches Objekt selbst. Im Idealfall werden Sie ResultSet.close() so bald wie möglich aufrufen, um Speicher freizugeben.

Ich rate Ihnen dringend, das zweite Kapitel von diesem Tutorial zu folgen ("SQL Statements verarbeiten") ).

    
RandomSeed 05.06.2013, 09:15
quelle