ROLLBACK TRANSACTION (Transact-SQL)
適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric のハードウェア SQL データベース
このステートメントは、明示的または暗黙的なトランザクションをトランザクションの先頭またはトランザクション内のセーブポイントにロールバックします。 ROLLBACK TRANSACTION
を使用すると、トランザクションの開始時またはセーブポイントに加えられたすべてのデータ変更を消去できます。 トランザクションが保持していたリソースも解放されます。
トランザクションのロールバックには、ローカル変数またはテーブル変数に加えられた変更は含まれません。 これらの変更は、このステートメントでは消去されません。
構文
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
有効なトランザクション名を含むユーザー定義変数の名前。 変数は、char、varchar、nchar、または nvarchar データ型を使用して宣言する必要があります。
savepoint_name
SAVE TRANSACTION
ステートメントからsavepoint_nameします。 savepoint_name は、識別子のルールに従っている必要があります。 savepoint_name は、条件付きのロールバックがトランザクションの一部にしか影響しない場合に使用します。
@savepoint_variable
有効なセーブポイント名を含むユーザー定義変数の名前。 変数は、char、varchar、nchar、または 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_COMMIT
ON
設定すると、ROLLBACK
は閉じますが、開いているすべてのカーソルの割り当てを解除するわけではありません。CURSOR_CLOSE_ON_COMMIT
OFF
設定すると、ROLLBACK
は、開いている同期STATIC
、INSENSITIVE
カーソル、または完全に設定された非同期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