ROLLBACK TRANSACTION (Transact-SQL)

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

このステートメントは、明示的または暗黙的なトランザクションをトランザクションの先頭またはトランザクション内のセーブポイントにロールバックします。 トランザクションの開始時またはセーブポイントに対して行われたすべてのデータ変更を消去するために使用 ROLLBACK TRANSACTION できます。 トランザクションが保持していたリソースも解放されます。

トランザクションのロールバックには、ローカル変数またはテーブル変数に加えられた変更は含まれません。 これらの変更は、このステートメントでは消去されません。

Transact-SQL 構文表記規則

構文

SQL Server および Azure SQL データベース の構文

ROLLBACK { TRAN | TRANSACTION }
    [ transaction_name | @tran_name_variable
    | savepoint_name | @savepoint_variable ]
[ ; ]

Microsoft Fabric、Azure Synapse Analytics、Parallel Data Warehouse データベースの Synapse Data Warehouse の構文。

ROLLBACK { TRAN | TRANSACTION }
[ ; ]

Note

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

引数

transaction_name

トランザクションに BEGIN TRANSACTION割り当てられた名前。 transaction_name は識別子のルールに従っている必要があります。ただし、使用されるのはトランザクション名の先頭の 32 文字だけです。 トランザクションを入れ子にする場合、 transaction_name は最も外側 BEGIN TRANSACTION のステートメントの名前である必要があります。 transaction_nameでは、SQL Server のインスタンスで大文字と小文字が区別されない場合でも、常に大文字と小文字が区別されます。

@tran_name_variable

有効なトランザクション名を含むユーザー定義変数の名前。 変数は、charvarcharnchar、または nvarchar データ型を使用して宣言する必要があります。

savepoint_name

ステートメントからSAVE TRANSACTIONsavepoint_nameします。 savepoint_name は、識別子のルールに従っている必要があります。 savepoint_name は、条件付きのロールバックがトランザクションの一部にしか影響しない場合に使用します。

@savepoint_variable

有効なセーブポイント名を含むユーザー定義変数の名前。 変数は、charvarcharnchar、または nvarchar データ型を使用して宣言する必要があります。

エラー処理

ROLLBACK TRANSACTIONステートメントでは、ユーザーへのメッセージは生成されません。 ストアド プロシージャまたはトリガーで警告が必要な場合は、or PRINT ステートメントをRAISERROR使用します。 RAISERROR は、エラーを示す推奨されるステートメントです。

解説

ROLLBACK TRANSACTIONトランザクションの先頭にロールバックsavepoint_nameまたはtransaction_nameはありません。 トランザクションを入れ子にすると、この同じステートメントによって、すべての内部トランザクションが最も外側 BEGIN TRANSACTION のステートメントにロールバックされます。 どちらの場合も、 ROLLBACK TRANSACTION システム関数を @@TRANCOUNT 0 にデクリメントします。 ROLLBACK TRANSACTION <savepoint_name> はデクリメント @@TRANCOUNTしません。

ROLLBACK TRANSACTIONでは、ローカル トランザクションで明示的にBEGIN DISTRIBUTED TRANSACTION開始された、またはローカル トランザクションからエスカレートされた分散トランザクションのsavepoint_nameを参照できません。

トランザクションは、ロールバック中のトランザクション内に含まれる入れ子になったトランザクションに関連付けられている場合COMMIT TRANSACTIONを除き、ステートメントの実行後COMMIT TRANSACTIONにロールバックすることはできません。 このインスタンスでは、入れ子になったトランザクションは、そのトランザクションを発行 COMMIT TRANSACTION した場合でもロールバックされます。

トランザクション内では、重複するセーブポイント名が許可されますが ROLLBACK TRANSACTION 、重複するセーブポイント名を使用すると、そのセーブポイント名を使用した最新 SAVE TRANSACTION の名前にのみロールバックされます。

相互運用性

ストアド プロシージャでは、 ROLLBACK TRANSACTION savepoint_nameまたはtransaction_nameを持たないステートメントは、すべてのステートメントを最も外側BEGIN TRANSACTIONにロールバックします。 ROLLBACK TRANSACTIONストアド プロシージャ@@TRANCOUNTが呼び出されたときの値とストアド プロシージャの完了@@TRANCOUNT時に異なる値を持つストアド プロシージャ内のステートメントは、情報メッセージを生成します。 このメッセージは、後続の処理には影響しません。

トリガーで a ROLLBACK TRANSACTION が発行された場合:

  • 現在のトランザクションのその時点までに加えられたすべてのデータ変更 (トリガーによって行われた変更も含む) がロールバックされます。

  • トリガーは、ステートメントの後メインステートメントの実行をROLLBACK続行します。 これらのステートメントのいずれかがデータを変更する場合、その変更はロールバックされません。 残りのステートメントを実行しても入れ子にしたトリガーは起動されません。

  • トリガーを発生させたステートメントの後のバッチ内のステートメントは実行されません。

@@TRANCOUNT は、自動コミット モードの場合でも、トリガーを入力するときに 1 ずつインクリメントされます。 つまり、トリガーは暗黙の入れ子にされたトランザクションとして扱われます。

ROLLBACK TRANSACTION ストアド プロシージャ内のステートメントは、プロシージャを呼び出したバッチ内の後続のステートメントには影響しません。バッチ内の後続のステートメントが実行されます。 ROLLBACK TRANSACTION トリガー内のステートメントは、トリガーを起動したステートメントを含むバッチを終了します。バッチ内の後続のステートメントは実行されません。

カーソルへの影響は、次の ROLLBACK 3 つの規則によって定義されます。

  • set ONを指定するとCURSOR_CLOSE_ON_COMMITROLLBACK閉じますが、開いているすべてのカーソルの割り当てが解除されるわけではありません。

  • set を使用CURSOR_CLOSE_ON_COMMITすると、ROLLBACK完全に設定された開いている同期STATICカーソルやINSENSITIVEカーソル、または非同期STATICカーソルには影響OFFしません。 他のタイプのオープン カーソルは、クローズしますが、割り当ては解除されません。

  • バッチを終了し、内部のロールバックを生成するエラーは、エラー ステートメントを含むバッチの中で宣言された、すべてのカーソルの割り当てを解除します。 カーソルの種類や設定に関係なく、すべてのカーソルの CURSOR_CLOSE_ON_COMMIT割り当てが解除されます。 これには、エラー バッチによって呼び出されるストアド プロシージャで宣言されたカーソルも含まれます。 エラー バッチの前にバッチで宣言されたカーソルは、最初の 2 つの規則の対象となります。 このタイプのエラーの例としてはデッドロック エラーがあります。 ROLLBACKトリガーで発行されたステートメントでも、この種類のエラーが自動的に生成されます。

ロック動作

ROLLBACK TRANSACTION savepoint_nameを指定するステートメントは、エスカレーションと変換を除き、セーブポイントを超えて取得されたすべてのロックを解放します。 これらのロックは解放されず、以前のロック モードに変換されません。

アクセス許可

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

次の例では、名前付きトランザクションをロールバックした場合の影響を示します。 テーブルを作成した後、次のステートメントは名前付きトランザクションを開始し、2 つの行を挿入してから、変数 @TransactionNameに指定されたトランザクションをロールバックします。 名前付きトランザクション外の外側にあるもう 1 つのステートメントで 2 行が挿入されます。 クエリによって、前のステートメントの結果が返されます。

USE tempdb;
GO

CREATE TABLE ValueTable ([value] INT);
GO

DECLARE @TransactionName VARCHAR(20) = 'Transaction1';

BEGIN TRANSACTION @TransactionName

INSERT INTO ValueTable
VALUES (1), (2);

ROLLBACK TRANSACTION @TransactionName;

INSERT INTO ValueTable
VALUES (3), (4);

SELECT [value]
FROM ValueTable;

DROP TABLE ValueTable;

結果セットは次のようになります。

value
-----
3
4