BEGIN TRANSACTION (Transact-SQL)

標示明確本機交易的起點。BEGIN TRANSACTION 會遞增 @@TRANCOUNT,遞增量是 1。

主題連結圖示Transact-SQL 語法慣例

語法

BEGIN { TRAN | TRANSACTION } 
    [ { transaction_name | @tran_name_variable }
      [ WITH MARK [ 'description' ] ]
    ]
[ ; ]

引數

  • transaction_name
    這是指派給交易的名稱。transaction_name 必須符合識別碼的規則,但不接受超出 32 個字元的識別碼。請只在巢狀 BEGIN...COMMIT 或 BEGIN...ROLLBACK 陳述式的最外一組使用交易名稱。

  • @tran_name_variable
    這是包含有效交易名稱之使用者定義變數的名稱。這個變數必須用 char、varchar、nchar 或 nvarchar 資料類型來宣告。如果有 32 個以上的字元傳給變數,只會使用前 32 個字元,其餘字元會截斷。

  • WITH MARK [ 'description' ]
    指定在記錄中標示交易。description 是說明標示的字串。超出 128 個字元的 description 值會先截斷成 128 個字元之後,才儲存在 msdb.dbo.logmarkhistory 資料表中。

    如果使用 WITH MARK,必須指定交易名稱。WITH MARK 可讓您將交易記錄還原到具名標記。

備註

BEGIN TRANSACTION 代表連接所參考的資料在邏輯和實體上都一致的點。如果發生錯誤,可以回復 BEGIN TRANSACTION 之後的所有資料修正,使資料返回這個已知的一致狀態。每項交易都會持續到它完成無誤,且發出 COMMIT TRANSACTION 使修正成為資料庫的永久部分為止,或持續到發生錯誤,且利用 ROLLBACK TRANSACTION 陳述式來清除所有修正為止。

BEGIN TRANSACTION 會針對發出陳述式的連接來啟動一項本機交易。依照目前的交易隔離等級設定而定,此時會取得許多資源來支援交易鎖定的連接所發出的 Transact-SQL 陳述式,直到利用 COMMIT TRANSACTION 或 ROLLBACK TRANSACTION 陳述式來完成它為止。交易長時間未完成會使其他使用者無法存取這些鎖定的資源,也會使記錄無法截斷。

雖然 BEGIN TRANSACTION 會啟動一項本機交易,但它並不會記錄在交易記錄中,直到應用程式後來執行必須記錄的動作 (如執行 INSERT、UPDATE 或 DELETE 陳述式) 為止。應用程式可以執行取得鎖定來保護 SELECT 陳述式的交易隔離等級之類的動作,但在應用程式執行修改動作之前,不會在記錄檔案留下任何記錄。

利用交易名稱在一系列巢狀交易中命名多項交易對交易的影響不大。系統只會登錄第一個 (最外層) 交易名稱。回復任何其他名稱 (不是有效的儲存點名稱) 都會產生錯誤。事實上在發生這個錯誤時,並不會回復在回復之前所執行的任何陳述式。只有當外部交易回復時,才會回復陳述式。

如果在認可或回復陳述式之前執行下列動作,BEGIN TRANSACTION 陳述式所啟動的本機交易會擴大到分散式交易:

  • 執行參考連結伺服器上遠端資料表的 INSERT、DELETE 或 UPDATE 陳述式。如果用來存取連結伺服器的 OLE DB 提供者不支援 ITransactionJoin 介面,INSERT、UPDATE 或 DELETE 陳述式會失敗。

  • 當 REMOTE_PROC_TRANSACTIONS 選項設為 ON 時,呼叫遠端預存程序。

SQL Server 的本機複本會成為交易控制器,且會利用 Microsoft 分散式交易協調器 (MS DTC) 來管理分散式交易。

您可以利用 BEGIN DISTRIBUTED TRANSACTION,將交易明確當做分散式交易來執行。如需詳細資訊,請參閱<BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)>。

標示的交易

WITH MARK 選項會使交易名稱出現在交易記錄中。當您將資料庫還原到較早的狀態時,可以利用標示的交易來取代日期和時間。如需詳細資訊,請參閱<使用標示的交易 (完整復原模式)>和<RESTORE (Transact-SQL)>。

另外,如果您必須將一組相關資料庫復原到邏輯一致的狀態,交易記錄標示便是必要的。分散式交易可以將標示放在這組相關資料庫的交易記錄中。將這組相關資料庫復原到這些標示會產生一組交易一致的資料庫。將標示放在相關資料庫中需要特殊程序。

只有當標示的交易更新資料庫時,才會將標示放在交易記錄中。未修改資料的交易不會有標示。

BEGIN TRAN new_name WITH MARK 可以透過巢狀結構方式放在沒有標示的現有交易內。當您這麼做時,雖然交易可能已有給定的名稱,但 new_name 會成為交易的標示名稱。在下列範例中,標示的名稱是 M2。

BEGIN TRAN T1;
UPDATE table1 ...;
BEGIN TRAN M2 WITH MARK;
UPDATE table2 ...;
SELECT * from table1;
COMMIT TRAN M2;
UPDATE table3 ...;
COMMIT TRAN T1;

當建立巢狀交易時,試圖標示已標示的交易會產生一則警告 (不是錯誤) 訊息:

"BEGIN TRAN T1 WITH MARK ...;"

"UPDATE table1 ...;"

"BEGIN TRAN M2 WITH MARK ...;"

"Server: Msg 3920, Level 16, State 1, Line 3"

"WITH MARK 選項只可套用至第一個 BEGIN TRAN WITH MARK。"

"已忽略選項。"

權限

需要 public 角色中的成員資格。

範例

A. 命名交易

下列範例顯示如何命名交易。

DECLARE @TranName VARCHAR(20);
SELECT @TranName = 'MyTransaction';

BEGIN TRANSACTION @TranName;
USE AdventureWorks2008R2;
DELETE FROM AdventureWorks2008R2.HumanResources.JobCandidate
    WHERE JobCandidateID = 13;

COMMIT TRANSACTION @TranName;
GO

B. 標示交易

下列範例顯示如何標示交易。已標示交易 CandidateDelete。

BEGIN TRANSACTION CandidateDelete
    WITH MARK N'Deleting a Job Candidate';
GO
USE AdventureWorks2008R2;
GO
DELETE FROM AdventureWorks2008R2.HumanResources.JobCandidate
    WHERE JobCandidateID = 13;
GO
COMMIT TRANSACTION CandidateDelete;
GO