Uso dei punti di salvataggio
I punti di salvataggio consentono di eseguire il rollback di parti di transazioni. In SQL Server è possibile creare un punto di salvataggio usando l'istruzione SAVE TRANSACTION savepoint_name. In seguito viene eseguita un'istruzione ROLLBACK TRANSACTION savepoint_name per eseguire il rollback del punto di salvataggio anziché della parte iniziale della transazione.
I punti di salvataggio risultano utili nelle situazioni in cui è improbabile che si verifichino degli errori. L'utilizzo di un punto di salvataggio per il rollback di parte di una transazione nel caso di errore non frequente può risultare più efficace rispetto a provare ciascuna transazione per verificare se un aggiornamento è valido prima di eseguire effettivamente l'aggiornamento. Poiché gli aggiornamenti e i rollback sono operazioni dispendiose, i punti di salvataggio sono efficaci solo se la probabilità che si verifichi l'errore è bassa e il costo del controllo preventivo della validità di un aggiornamento è relativamente alto.
Microsoft JDBC Driver per SQL Server supporta l'uso dei punti di salvataggio tramite i metodi setSavepoint della classe SQLServerConnection. Il metodo setSavepoint consente di creare un punto di salvataggio con nome o senza nome nell'ambito della transazione corrente e restituirà un oggetto SQLServerSavepoint. È possibile creare più punti di salvataggio all'interno di una transazione. Per eseguire il rollback di una transazione fino a un determinato punto di salvataggio, è possibile passare l'oggetto SQLServerSavepoint al metodo rollback (java.sql.Savepoint).
Nell'esempio seguente viene usato un punto di salvataggio durante l'esecuzione di una transazione locale composta da due istruzioni separate nel blocco try
. Le istruzioni vengono eseguite nella tabella Production.ScrapReason del database di esempio AdventureWorks2022 e il punto di salvataggio viene usato per eseguire il rollback della seconda istruzione. In questo modo viene eseguito il commit solo della prima istruzione nel database.
public static void executeTransaction(Connection con) {
try(Statement stmt = con.createStatement();) {
con.setAutoCommit(false);
stmt.executeUpdate("INSERT INTO Production.ScrapReason(Name) VALUES('Correct width')");
Savepoint save = con.setSavepoint();
stmt.executeUpdate("INSERT INTO Production.ScrapReason(Name) VALUES('Wrong width')");
con.rollback(save);
con.commit();
System.out.println("Transaction succeeded.");
}
catch (SQLException ex) {
ex.printStackTrace();
try {
System.out.println("Transaction failed.");
con.rollback();
}
catch (SQLException se) {
se.printStackTrace();
}
}
}