Share via


BEGIN TRANSACTION (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric のウェアハウス

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

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

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

transaction_name

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

トランザクションに割り当てられた名前。 transaction_name識別子の規則に準拠する必要がありますが、32 文字を超える識別子は許可されません。 入れ子になったステートメントBEGIN...ROLLBACKの最も外側のペアでのみトランザクション名をBEGIN...COMMIT使用します。 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 文字を超える説明は、テーブルに格納される前に 128 文字にmsdb.dbo.logmarkhistory切り捨てられます。

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

解説

BEGIN TRANSACTIONは次の値でインクリメントされます@@TRANCOUNT1

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

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

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

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

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

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

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

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

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

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

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

この WITH MARK オプションを指定すると、トランザクション名がトランザクション ログに格納されます。 データベースを以前の状態に復元すると、日付と時刻の代わりにマークされたトランザクションを使用できます。 詳細については、「 マークされたトランザクションを使用して関連データベースを一貫して 復旧する」および 「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 サンプル データベースを使用します。このサンプル データベースは、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