Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Точки сохранения позволяют откатывать части транзакций. В SQL Server точку сохранения можно создать с помощью инструкции SAVE TRANSACTION savepoint_name. Позже вы выполняете инструкцию ROLLBACK TRANSACTION savepoint_name для отката к точке сохранения, а не к началу транзакции.
Точки сохранения удобно использовать, когда вероятность возникновения ошибок мала. Использование точки сохранения для отката части транзакции в случае редкой ошибки может быть более эффективным, чем подход, при котором каждая транзакция перед выполнением обновления проверяет, допустимо ли это обновление. Операции обновления и отката затратны, поэтому использование точек сохранения эффективно только в том случае, если вероятность возникновения ошибки низка, а затраты на предварительную проверку корректности обновления относительно высоки.
Драйвер Microsoft JDBC для SQL Server поддерживает использование точек сохранения посредством метода setSavepoint класса SQLServerConnection. С помощью метода setSavepoint можно создать именованную или неименованную точку сохранения в текущей транзакции, а метод возвращает объект SQLServerSavepoint. В транзакции можно создать несколько точек сохранения. Для отката транзакции до заданной точки сохранения можно передать объект SQLServerSavepoint в метод rollback (java.sql.Savepoint).
В приведенном ниже примере используется точка сохранения при выполнении локальной транзакции, состоящей из двух раздельных инструкций в блоке try. Инструкции выполняются в таблице Production.ScrapReason в примере базы данных AdventureWorks2025, а для отката второй инструкции используется точка сохранения. При этом в базе данных фиксируется только первая инструкция.
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();
}
}
}