COMMIT TRANSACTION (Transact-SQL)

Отмечает успешное завершение явной или неявной транзакции. Если значение @@TRANCOUNT равно 1, то инструкция COMMIT TRANSACTION выполняет все изменения, сделанные с начала транзакции постоянной частью базы данных, освобождает ресурсы, удерживаемые транзакцией, и уменьшает значение параметра @@TRANCOUNT до 0. Если значение переменной @@TRANCOUNT больше 1, инструкция COMMIT TRANSACTION уменьшает значение @@TRANCOUNT только на 1 и оставляет транзакцию активной.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

COMMIT { TRAN | TRANSACTION } [ transaction_name | @tran_name_variable ] ]
[ ; ]

Аргументы

  • transaction_name
    Не используется в компоненте SQL Server Database Engine. Аргумент transaction_name указывает имя транзакции, присвоенное предыдущей инструкцией BEGIN TRANSACTION. Аргумент transaction_name должен подчиняться правилам для идентификаторов, но не может превышать 32 символов. Аргумент transaction_name может использоваться как подсказка, показывающая программистам, с какими вложенными инструкциями BEGIN TRANSACTION связана инструкция COMMIT TRANSACTION.

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

Замечания

Обязанностью программиста на языке Transact-SQL является вызов инструкции COMMIT TRANSACTION только в том случае, когда все данные, относящиеся к транзакции, логически верны.

Если зафиксированная транзакция является распределенной транзакцией Transact-SQL, инструкция COMMIT TRANSACTION вызывает координатор MS DTC для использования двухфазного протокола фиксации на всех серверах, участвующих в транзакции. Если локальная транзакция охватывает две или более базы данных одного и того же экземпляра компонента Database Engine, то экземпляр использует встроенный двухэтапный алгоритм для фиксирования всех баз данных, вызванных в транзакции.

При использовании вложенных транзакций фиксация внутренних транзакций не освобождает ресурсы и не делает их изменения постоянными. Изменения данных становятся постоянными и освобождаются ресурсы только при фиксации внешней транзакции. Вызов каждой инструкции COMMIT TRANSACTION приводит к тому, что если значение @@TRANCOUNT больше 1, то значение переменной @@TRANCOUNT просто уменьшается на 1. Когда значение @@TRANCOUNT уменьшится до нуля, вся внешняя транзакция фиксируется. Так как аргумент transaction_name не учитывается компонентом Database Engine, то вызов инструкции COMMIT TRANSACTION, содержащей ссылку на имя внешней транзакции, приводит к тому, что если существуют необработанные внутренние транзакции, то производится только уменьшение значения параметра @@TRANCOUNT на 1.

Вызов инструкции COMMIT TRANSACTION, когда значение параметра @@TRANCOUNT равно нулю, дает ошибку, так как нет соответствующей инструкции BEGIN TRANSACTION.

Нельзя произвести откат транзакции после вызова инструкции COMMIT TRANSACTION, так как измененные данные уже стали частью базы данных.

Компонент Database Engine в SQL Server 2000 и более поздних версиях увеличивает счетчик транзакций внутри выражения, только когда счетчик транзакций равен нулю при запуске инструкции. В версии 7.0 SQL Server счетчик транзакций всегда увеличивается вне зависимости от значения счетчика транзакций при запуске инструкции. Это может послужить причиной того, что значение, возвращаемое параметром @@TRANCOUNT в триггерах для SQL Server 2000 и более поздних версий, будет меньше, чем в SQL Server версии 7.0.

В SQL Server 2000 и более поздних версиях, если инструкции COMMIT TRANSACTION или COMMIT WORK выполняются в триггере и нет соответствующей явной или неявной инструкции BEGIN TRANSACTION при запуске триггера, пользователи могут наблюдать иное поведения, нежели в SQL Server версии 7.0. Помещение инструкций COMMIT TRANSACTION или COMMIT WORK в триггеры не рекомендуется.

Разрешения

Требуется членство в роли public.

Примеры

А. Фиксация транзакции

В следующем примере удаляется кандидат на вакансию.

USE AdventureWorks2008R2;
GO
BEGIN TRANSACTION;
GO
DELETE FROM HumanResources.JobCandidate
    WHERE JobCandidateID = 13;
GO
COMMIT TRANSACTION;
GO

Б. Фиксация вложенной транзакции

В следующем примере создается таблица и формируется три уровня вложенных транзакций, которые затем фиксируются. Хотя каждая инструкция COMMIT TRANSACTION имеет параметр transaction_name, не существует связи между инструкциями COMMIT TRANSACTION и BEGIN TRANSACTION. Параметры transaction_name удобны для понимания и помогают программисту удостовериться в том, что закодировано верное количество фиксированных транзакций, чтобы уменьшить значение параметра @@TRANCOUNT до 0 и таким образом зафиксировать внешнюю транзакцию.

USE AdventureWorks2008R2;
GO
IF OBJECT_ID(N'TestTran',N'U') IS NOT NULL
    DROP TABLE TestTran;
GO
CREATE TABLE TestTran (Cola int PRIMARY KEY, Colb char(3));
GO
-- This statement sets @@TRANCOUNT to 1.
BEGIN TRANSACTION OuterTran;
GO
PRINT N'Transaction count after BEGIN OuterTran = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (1, 'aaa');
GO
-- This statement sets @@TRANCOUNT to 2.
BEGIN TRANSACTION Inner1;
GO
PRINT N'Transaction count after BEGIN Inner1 = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (2, 'bbb');
GO
-- This statement sets @@TRANCOUNT to 3.
BEGIN TRANSACTION Inner2;
GO
PRINT N'Transaction count after BEGIN Inner2 = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO
INSERT INTO TestTran VALUES (3, 'ccc');
GO
-- This statement decrements @@TRANCOUNT to 2.
-- Nothing is committed.
COMMIT TRANSACTION Inner2;
GO
PRINT N'Transaction count after COMMIT Inner2 = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO
-- This statement decrements @@TRANCOUNT to 1.
-- Nothing is committed.
COMMIT TRANSACTION Inner1;
GO
PRINT N'Transaction count after COMMIT Inner1 = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO
-- This statement decrements @@TRANCOUNT to 0 and
-- commits outer transaction OuterTran.
COMMIT TRANSACTION OuterTran;
GO
PRINT N'Transaction count after COMMIT OuterTran = '
    + CAST(@@TRANCOUNT AS nvarchar(10));
GO