Поделиться через


Использование точек сохранения

Скачать драйвер JDBC

Точки сохранения предоставляют механизм отката части транзакций. В 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 в образце базы данных AdventureWorks2022, а точка сохранения используется для отката второй инструкции. При этом в базе данных фиксируется только первая инструкция.

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();
        }
    }
}

См. также раздел

Выполнение транзакций с помощью JDBC Driver