ROLLBACK TRANSACTION (Transact-SQL)

適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics 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 }
[ ; ]

引数

transaction_name

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

@tran_name_variable

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

savepoint_name

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

@savepoint_variable

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

エラー処理

ROLLBACK TRANSACTION ステートメントでは、ユーザーへのメッセージは生成されません。 ストアド プロシージャまたはトリガーで警告が必要な場合は、 RAISERROR または PRINT ステートメントを使用します。 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 にのみロールバックされます。

相互運用性

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

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

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

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

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

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

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

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

  • CURSOR_CLOSE_ON_COMMITON設定すると、ROLLBACKは閉じますが、開いているすべてのカーソルの割り当てを解除するわけではありません。

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

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

ロック動作

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

アクセス許可

ロール 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