Sql Server 事務嵌套

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 ] ]
[ ; ]

僅當事務被引用所有數據的邏輯都正確時,Transact-SQL 程序員才應發出 COMMIT TRANSACTION 命令。

如果所提交的事務是 Transact-SQL 分佈式事務,COMMIT TRANSACTION 將觸發 MS DTC 使用兩階段提交協議,以便提交所有涉及該事務的服務器。如果本地事務跨越同一數據庫引擎實例上的兩個或多個數據庫,則該實例將使用內部的兩階段提交來提交所有涉及該事務的數據庫。

當在嵌套事務中使用時,內部事務的提交併不釋放資源或使其修改成爲永久修改。只有在提交了外部事務時,數據修改才具有永久性,而且資源纔會被釋放。當 @@TRANCOUNT 大於 1 時,每發出一個 COMMIT TRANSACTION 命令只會使 @@TRANCOUNT 按 1 遞減。當 @@TRANCOUNT 最終遞減爲 0 時,將提交整個外部事務。因爲 transaction_name 被數據庫引擎忽略,所以當存在顯著內部事務時,發出一個引用外部事務名稱的 COMMIT TRANSACTION 只會使 @@TRANCOUNT 按 1 遞減。

當 @@TRANCOUNT 爲 0 時發出 COMMIT TRANSACTION 將會導致出現錯誤;因爲沒有相應的 BEGIN TRANSACTION。

不能在發出一個 COMMIT TRANSACTION 語句之後回滾事務,因爲數據修改已經成爲數據庫的一個永久部分。

僅當事務計數在語句開始處爲 0 時,SQL Server 2000 及更高版本中的數據庫引擎纔會增加語句內的事務計數。在 SQL Server 7.0 版中,事務計數始終增加,而不考慮在語句開始處爲何值。這可能會導致 SQL Server 2000 及更高版本的觸發器的 @@TRANCOUNT 中返回的值低於 SQL Server 7.0 版中的對應值。

在 SQL Server 2000 及更高版本中,如果在觸發器中執行 COMMIT TRANSACTION 或 COMMIT WORK 語句,並且在觸發器的開始位置沒有對應的顯式或隱式 BEGIN TRANSACTION 語句,則用戶看到的行爲可能與在 SQL Server 7.0 版中看到的行爲有所不同。建議不要在觸發器中使用 COMMIT TRANSACTION 或 COMMIT WORK 語句。

要求具有 public 角色成員資格。

A. 提交事務。

此示例將刪除候選作業。

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

B. 提交嵌套事務。

以下示例創建一個表,生成三個級別的嵌套事務,然後提交該嵌套事務。儘管每個 COMMIT TRANSACTION 語句都有一個 transaction_name 參數,但是 COMMIT TRANSACTION 和 BEGIN TRANSACTION 語句之間沒有任何關係。transaction_name 參數僅是幫助閱讀的方法,可幫助程序員確保提交的正確號碼被編碼以便將 @@TRANCOUNT 減少到 0,從而提交外部事務。

USE AdventureWorks;
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章