BEGIN TRANSACTION (Transact-SQL)

適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric のウェアハウス

明示的なローカル トランザクションの開始位置をマークします。 明示的なトランザクションは、 BEGIN TRANSACTION ステートメントで始まり、 COMMIT または ROLLBACK ステートメントで終わる。

Transact-SQL 構文表記規則

構文

SQL Server、Azure SQL Database、および Azure SQL Managed Instance の構文。

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

Microsoft Fabric、Azure Synapse Analytics および Analytics Platform System (PDW) での Synapse Data Warehouse の構文。

BEGIN { TRAN | TRANSACTION }
[ ; ]

引数

transaction_name

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、および Azure SQL Managed Instance

トランザクションに割り当てられた名前。 transaction_name 識別子の規則に準拠する必要がありますが、32 文字を超える識別子は許可されません。 入れ子になった BEGIN...COMMIT または BEGIN...ROLLBACK ステートメントの最も外側のペアでのみトランザクション名を使用します。 SQL Server のインスタンスで大文字と小文字が区別されない場合でも、transaction_name では常に大文字と小文字が区別されます。

@tran_name_variable

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、および Azure SQL Managed Instance

有効なトランザクション名を含むユーザー定義変数の名前。 変数は、charvarcharnchar、または nvarchar データ型を使用して宣言する必要があります。 32 文字を超える文字が変数に渡される場合は、最初の 32 文字のみが使用されます。 残りの文字は切り捨てられます。

WITH MARK [ 'description' ]

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、および Azure SQL Managed Instance

ログの中でトランザクションにマークを付けます。 description は、マーク名を示す文字列です。 指定 128 文字を超える文字は、msdb.dbo.logmarkhistory テーブルに格納される前に 128 文字に切り捨てられます。

WITH MARKを使用する場合は、トランザクション名を指定する必要があります。 WITH MARK では、トランザクション ログを名前付きマークに復元できます。

解説

BEGIN TRANSACTION1@@TRANCOUNTインクリメントします。

BEGIN TRANSACTION は、接続によって参照されるデータが論理的かつ物理的に一貫性のあるポイントを表します。 エラーが発生した場合、 BEGIN TRANSACTION 後に行われたすべてのデータ変更をロールバックして、この既知の整合性状態にデータを返すことができます。 各トランザクションは、エラーなしで完了し、変更をデータベースの永続的な部分にするために COMMIT TRANSACTION が発行されるか、エラーが発生し、すべての変更が ROLLBACK TRANSACTION ステートメントで消去されるまで続きます。

BEGIN TRANSACTION は、ステートメントを発行する接続のローカル トランザクションを開始します。 現在のトランザクション分離レベルの設定に応じて、接続によって発行された Transact-SQL ステートメントをサポートするために取得された多くのリソースは、 COMMIT TRANSACTION または ROLLBACK TRANSACTION ステートメントで完了するまでトランザクションによってロックされます。 トランザクションが完了するまでの間、他のユーザーはロックされたリソースにアクセスできなくなります。また、ログの切り捨ても行われません。

BEGIN TRANSACTIONはローカル トランザクションを開始しますが、アプリケーションがログに記録する必要があるアクション (INSERTUPDATEDELETE ステートメントの実行など) を実行するまで、トランザクション ログに記録されません。 アプリケーションは、 SELECT ステートメントのトランザクション分離レベルを保護するためのロックの取得などのアクションを実行できますが、アプリケーションが変更アクションを実行するまでログには何も記録されません。

1 つのトランザクション名で、何重にも入れ子になったトランザクション内の複数のトランザクションを指定しても、トランザクションに影響はほとんどありません。 システムに登録されるのは、最初の (最も外側の) トランザクション名だけです。 他の名前にロールバックするとエラーが発生します。ただし、有効なセーブポイント名へのロールバックではエラーは発生しません。 このエラーが発生した場合、ロールバック前に実行されたステートメントは一切ロールバックされません。 ステートメントは、外側のトランザクションがロールバックされた場合にのみロールバックされます。

ステートメントがコミットまたはロールバックされる前に次のアクションが実行された場合、 BEGIN TRANSACTION ステートメントによって開始されたローカル トランザクションは分散トランザクションにエスカレートされます。

  • リンク サーバー上のリモート テーブルを参照する INSERTDELETE、または UPDATE ステートメントが実行されます。 リンク サーバーへのアクセスに使用する OLE DB プロバイダーがITransactionJoin インターフェイスをサポートしていない場合、INSERTUPDATE、またはDELETEステートメントは失敗します。

  • REMOTE_PROC_TRANSACTIONS オプションが ON に設定されている場合、リモート ストアド プロシージャの呼び出しが行われます。

SQL Server のローカル コピーはトランザクションのコントローラーになり、Microsoft 分散トランザクション コーディネーター (MS DTC) を使用して分散トランザクションを管理します。

トランザクションは、 BEGIN DISTRIBUTED TRANSACTIONを使用して分散トランザクションとして明示的に実行できます。 詳細については、「 BEGIN DISTRIBUTED TRANSACTION」を参照してください。

SET IMPLICIT_TRANSACTIONSON に設定すると、BEGIN TRANSACTION ステートメントによって 2 つの入れ子になったトランザクションが作成されます。 詳しくは、「SET IMPLICIT_TRANSACTIONS」をご覧ください。

マークされたトランザクション

WITH MARK オプションを指定すると、トランザクション名がトランザクション ログに格納されます。 データベースを以前の状態に復元すると、日付と時刻の代わりにマークされたトランザクションを使用できます。 詳細については、「 マークされたトランザクションを使用して関連データベースを一貫して復旧する RESTORE ステートメントと RESTORE ステートメントを使用するを参照してください。

さらに、関連するデータベースのセットを論理的に一貫した状態に復元する必要がある場合は、トランザクション ログ マークが必要です。 分散トランザクションによって、関連するデータベースのトランザクション ログにマークを設定できます。 関連するデータベースのセットをこれらのマークに復元すると、トランザクションとして一貫性のあるデータベースのセットが作成されます。 関連するデータベースにマークを設定するには、特別な手順が必要です。

トランザクション ログにマークが設定されるのは、マーク付きのトランザクションによってデータベースが更新される場合のみです。 データを変更しないトランザクションはマークされません。

BEGIN TRANSACTION <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;

トランザクションを入れ子にすると、既にマークされているトランザクションをマークしようとすると、次の警告メッセージが表示されます。

Server: Msg 3920, Level 16, State 1, Line 3
WITH MARK option only applies to the first BEGIN TRAN WITH MARK.
The option is ignored.

アクセス許可

ロール public のメンバーシップが必要です。

この記事の Transact-SQL コード サンプルは AdventureWorks2022 または AdventureWorksDW2022 サンプル データベースを使用します。このサンプル データベースは、Microsoft SQL Server サンプルとコミュニティ プロジェクトのホーム ページからダウンロードできます。

A. 明示的なトランザクションを使用する

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、Analytics Platform System (PDW)

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

B. トランザクションのロールバック

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、Analytics Platform System (PDW)

次の例では、トランザクションのロールバックの効果を示します。 この例では、 ROLLBACK ステートメントは INSERT ステートメントをロールバックしますが、作成されたテーブルは引き続き存在します。

CREATE TABLE ValueTable (id INT);
BEGIN TRANSACTION;
    INSERT INTO ValueTable VALUES(1);
    INSERT INTO ValueTable VALUES(2);
ROLLBACK;

C: トランザクションに名前を付けます

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、Azure SQL Managed Instance

次の例では、トランザクションの名前を指定する方法を示します。

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

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

COMMIT TRANSACTION @TranName;
GO

D. トランザクションをマークする

適用対象: SQL Server 2008 (10.0.x) 以降のバージョン、Azure SQL Database、Azure SQL Managed Instance

次の例では、トランザクションにマークを付ける方法を示します。 トランザクション CandidateDelete にマークが付けられています。

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