Ho un blocco di codice che aggiorna i record in un database. Esempio ridotto:Posso riutilizzare un PreparedStatement se riscontra un'eccezione transitoria?
...
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();
...
Questo è parte di un codice, che sta elaborando un sacco di record, e il codice è in esecuzione un sacco di fili per la velocità. Va tutto bene, ma man mano che il carico aumenta sull'ambiente live, ho notato che sono stati lanciati alcuni SQLTransientException
s. Sembra che non posso fare nulla su questi, tranne ritentare la transazione.
La mia domanda è: il lotto potrebbe essere stato cancellato anche se l'istruzione non è riuscita? Devo semplicemente riprovare semplicemente la riga executeBatch
o devo ricreare l'intero batch? Ed è lo stesso per le dichiarazioni non batch?
In breve, e più in generale, questo è un buon modo per gestire le eccezioni transitorie?
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;
}
}
}
Ho taggato questa domanda MySQL perché è quello che stiamo attualmente utilizzando, ma sto cercando di capire il comportamento standard, piuttosto che il comportamento specifico dell'implementazione, dal momento che stiamo migrando presto a Postgres. – Dave
In teoria 'SQLTransientException' deve essere lanciato solo se l'errore consente operazioni che possono essere riprovate senza" senza alcun intervento da parte delle funzionalità a livello di applicazione ". –
Avete uno stato SQL per questa eccezione (getSQLState())? – Mani