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


СОХРАНИТЬ ТРАНЗАКЦИЮ (Transact-SQL)

Применимо к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureБаза данных SQL в Microsoft Fabric

Устанавливает точку сохранения внутри транзакции.

Соглашения о синтаксисе Transact-SQL

Syntax

SAVE { TRAN | TRANSACTION } { savepoint_name | @savepoint_variable }
[ ; ]

Arguments

savepoint_name

Имя, назначенное точке сохранения. Имена точек сохранения должны соответствовать правилам для идентификаторов, но ограничены 32 символами. savepoint_name всегда учитывает регистр, даже если экземпляр ядра СУБД не учитывает регистр.

@savepoint_variable

Имя определяемой пользователем переменной, содержащей допустимое имя точки сохранения. Переменная должна быть объявлена с типом данных char, varchar, nchar или nvarchar. В переменную можно передать более 32 символов, но используются только первые 32 символа.

Remarks

Вы можете задать точку сохранения в транзакции. Точка сохранения определяет состояние согласованности, к которому транзакция может возвращать, если часть транзакции условно отменена. Если транзакция откатывается в точку сохранения, она должна перейти к завершению с дополнительными Transact-SQL операторами при необходимости и COMMIT TRANSACTION оператором или полностью отменить, откатив транзакцию обратно к началу. Чтобы отменить всю транзакцию, используйте форму ROLLBACK TRANSACTION transaction_name. Отменяются все инструкции или процедуры транзакции.

Повторяющиеся имена точек сохранения разрешены в транзакции, но ROLLBACK TRANSACTION инструкция, указывающая имя точки сохранения, возвращает транзакцию только к последнему SAVE TRANSACTION с помощью этого имени.

SAVE TRANSACTION не поддерживается в распределенных транзакциях, запущенных явным образом BEGIN DISTRIBUTED TRANSACTION или повышено из локальной транзакции.

Замечание

Ядро СУБД не поддерживает независимо управляемые вложенные транзакции. Фиксация внутренних транзакций уменьшается @@TRANCOUNT , но не имеет других последствий. Откат внутренней транзакции всегда откатывает внешнюю транзакцию, если точка сохранения не существует и не указана в инструкции ROLLBACK .

Поведение блокировки

Инструкция ROLLBACK TRANSACTION , указывающая savepoint_name освобождает все блокировки, приобретенные за пределами точки сохранения, за исключением эскалации и преобразованных блокировок. Эти блокировки не выпускаются, и они не преобразуются обратно в предыдущий режим блокировки.

Permissions

Необходимо членство в роли public.

Examples

Примеры кода в этой статье используют базу данных образца AdventureWorks2025 или AdventureWorksDW2025, которую можно скачать с домашней страницы образцов и проектов сообщества Microsoft SQL Server и.

В следующем примере показано, как использовать точку сохранения транзакций для отката только изменений, внесенных хранимой процедурой, если транзакция запущена перед выполнением хранимой процедуры.

IF EXISTS (SELECT name FROM sys.objects
           WHERE name = N'SaveTranExample')
    DROP PROCEDURE SaveTranExample;
GO

CREATE PROCEDURE SaveTranExample
    @InputCandidateID INT
AS
-- Detect whether the procedure was called
-- from an active transaction and save
-- that for later use.
-- In the procedure, @TranCounter = 0
-- means there was no active transaction
-- and the procedure started one.
-- @TranCounter > 0 means an active
-- transaction was started before the
-- procedure was called.
DECLARE @TranCounter INT;
SET @TranCounter = @@TRANCOUNT;

IF @TranCounter > 0
    -- Procedure called when there is
    -- an active transaction.
    -- Create a savepoint to be able
    -- to roll back only the work done
    -- in the procedure if there is an
    -- error.
    SAVE TRANSACTION ProcedureSave;
ELSE
    -- Procedure must start its own
    -- transaction.
    BEGIN TRANSACTION;
-- Modify database.
BEGIN TRY
    DELETE HumanResources.JobCandidate
        WHERE JobCandidateID = @InputCandidateID;
    -- Get here if no errors; must commit
    -- any transaction started in the
    -- procedure, but not commit a transaction
    -- started before the transaction was called.
    IF @TranCounter = 0
        -- @TranCounter = 0 means no transaction was
        -- started before the procedure was called.
        -- The procedure must commit the transaction
        -- it started.
        COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- An error occurred; must determine
    -- which type of rollback will roll
    -- back only the work done in the
    -- procedure.
    IF @TranCounter = 0
        -- Transaction started in procedure.
        -- Roll back complete transaction.
        ROLLBACK TRANSACTION;
    ELSE
        -- Transaction started before procedure
        -- called, do not roll back modifications
        -- made before the procedure was called.
        IF XACT_STATE() <> -1
            -- If the transaction is still valid, just
            -- roll back to the savepoint set at the
            -- start of the stored procedure.
            ROLLBACK TRANSACTION ProcedureSave;
            -- If the transaction is uncommitable, a
            -- rollback to the savepoint is not allowed
            -- because the savepoint rollback writes to
            -- the log. Just return to the caller, which
            -- should roll back the outer transaction.

    -- After the appropriate rollback, return error
    -- information to the caller.
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT @ErrorMessage = ERROR_MESSAGE();
    SELECT @ErrorSeverity = ERROR_SEVERITY();
    SELECT @ErrorState = ERROR_STATE();

    RAISERROR (
              @ErrorMessage, -- Message text.
              @ErrorSeverity, -- Severity.
              @ErrorState -- State.
              );
END CATCH
GO