Ich habe einen Block von Code, der Datensätze in einer Datenbank aktualisiert. Reduziertes Beispiel:Kann ich PreparedStatement erneut verwenden, wenn eine vorübergehende Ausnahme auftritt?
...
statement = connection.prepareStatement(
"INSERT INTO thistable (name) VALUES (?)",
PreparedStatement.RETURN_GENERATED_KEYS
);
statement.setString(1, "Fred");
statement.addBatch();
statement.setString(2, "Joe");
statement.addBatch();
statement.executeBatch();
...
Dieser Teil von Code ist die verarbeitet ein viel von Datensätzen, und der Code eine Menge Threads für Geschwindigkeit läuft. Das ist alles in Ordnung, aber als die Last in der Live-Umgebung steigt, habe ich bemerkt, dass ein paar SQLTransientException
s geworfen werden. Es scheint, dass ich nichts dagegen tun kann, außer die Transaktion erneut zu versuchen.
Meine Frage ist: Könnte der Stapel gelöscht worden sein, obwohl die Anweisung fehlgeschlagen ist? Bin ich OK, einfach die executeBatch
Zeile erneut zu versuchen, oder muss ich den gesamten Stapel neu erstellen? Und ist das für Nicht-Batch-Anweisungen das gleiche?
Kurz gesagt und allgemein, ist dies eine gute Möglichkeit, vorübergehende Ausnahmen zu behandeln?
statement.setString(1, "Fred");
statement.addBatch();
statement.setString(2, "Joe");
statement.addBatch();
for(int attempt = 0; ; attempt ++) {
try {
statement.executeBatch();
break;
} catch(SQLTransientException ex) {
if(attempt >= 3) {
throw ex;
}
try {
Thread.sleep(attempt * attempt * 100);
} catch(InterruptedException ex2) {
throw ex;
}
}
}
Ich habe diese Frage mit MySQL getaggt, weil wir sie gerade verwenden, aber ich möchte das Standardverhalten und nicht das implementierungsspezifische Verhalten verstehen, da wir bald auf Postgres migrieren werden. – Dave
Theoretisch sollte 'SQLTransientException' nur ausgelöst werden, wenn der Fehler Operationen zulässt, die ohne" ohne Eingreifen der Funktionalität auf Anwendungsebene "wiederholt werden können. –
Haben Sie einen SQL-Status für diese Ausnahme (getSQLState())? – Mani