明示的なトランザクションはネストできます。これは、トランザクションの既存のプロセスからでもアクティブ トランザクションがないプロセスからでも呼び出せるストアド プロシージャ内のトランザクションをサポートすることを主な目的としています。
次の例は、ネストしたトランザクションの使用方法を示しています。プロシージャ TransProc は、実行するプロセスのトランザクション モードに関係なくトランザクションを設定します。トランザクションがアクティブなときに TransProc を呼び出すと、TransProc 内のネストしたトランザクションの大部分は無視され、外側のトランザクションに対する最終措置に基づいて INSERT ステートメントがコミットまたはロールバックされます。未完了のトランザクションがないプロセスが TransProc を実行した場合、プロシージャの終了時に COMMIT TRANSACTION が INSERT ステートメントを完全にコミットします。
SET QUOTED_IDENTIFIER OFF
GO
SET NOCOUNT OFF
GO
USE pubs
GO
CREATE TABLE TestTrans(Cola INT PRIMARY KEY,
Colb CHAR(3) NOT NULL)
GO
CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS
BEGIN TRANSACTION InProc
INSERT INTO TestTrans VALUES (@PriKey, @CharCol)
INSERT INTO TestTrans VALUES (@PriKey + 1, @CharCol)
COMMIT TRANSACTION InProc
GO
/* Start a transaction and execute TransProc */
BEGIN TRANSACTION OutOfProc
GO
EXEC TransProc 1, 'aaa'
GO
/* Roll back the outer transaction, this will
roll back TransProc's nested transaction */
ROLLBACK TRANSACTION OutOfProc
GO
EXECUTE TransProc 3,'bbb'
GO
/* The following SELECT statement shows only rows 3 and 4 are
still in the table. This indicates that the commit
of the inner transaction from the first EXECUTE statement of
TransProc was overridden by the subsequent rollback. */
SELECT * FROM TestTrans
GO
Microsoft® SQL Server™ は、内部トランザクションのコミットを無視します。トランザクションは、最も外側のトランザクションが終了したときの処理に基づいてコミットまたはロールバックされます。外側のトランザクションがコミットされた場合、ネストした内部トランザクションもコミットされます。外側のトランザクションがロールバックされた場合、内部トランザクションが個々にコミットされているかどうかに関係なく、内部トランザクションもすべてがロールバックされます。
COMMIT TRANSACTION または COMMIT WORK が呼び出された場合、最後に実行された BEGIN TRANSACTION に適用されます。BEGIN TRANSACTION ステートメントがネストしている場合、最後にネストしたトランザクションつまり最も内側のトランザクションだけに COMMIT ステートメントが適用されます。ネストしたトランザクション内の COMMIT TRANSACTION transaction_name ステートメントが外側のトランザクションの名前を参照していても、コミットされるのは最も内側のトランザクションだけです。
ネストしたトランザクションの内側のトランザクションの名前を ROLLBACK TRANSACTION ステートメントのパラメータ transaction_name で指定しても無効です。transaction name で指定できるのは最も外側のトランザクションの名前だけです。ROLLBACK TRANSACTION transaction_name ステートメントで外側のトランザクションの名前を指定して、ネストしたトランザクションの任意のレベルで実行した場合、ネストしたトランザクションはすべてがロールバックされます。ネストしたトランザクションの任意のレベルでパラメータ transaction_name を指定しないで ROLLBACK WORK ステートメントまたは ROLLBACK TRANSACTION ステートメントを実行した場合は、最も外側のトランザクションを含む、ネストしたすべてのトランザクションがロールバックされます。
@@TRANCOUNT 関数は、現在のトランザクションのネスト レベルを記録します。BEGIN TRANSACTION ステートメントは @@TRANCOUNT を 1 ずつ増やします。COMMIT TRANSACTION ステートメントまたは COMMIT WORK ステートメントは @@TRANCOUNT を 1 ずつ減らします。ROLLBACK WORK ステートメントまたは ROLLBACK TRANSACTION ステートメントでトランザクション名を指定しない場合、ネストしたトランザクションがすべてロールバックされ、@@TRANCOUNT は 0 になります。ROLLBACK TRANSACTION でネストしたトランザクションの最も外側のトランザクションの名前を指定した場合、ネストしたトランザクションがすべてロールバックされ、@@TRANCOUNT は 0 になります。トランザクションにいるかどうかが確かでない場合は、SELECT @@TRANCOUNT を指定して、@@TRANCOUNT が 1 以上かどうかを調べます。@@TRANCOUNT が 0 の場合は、トランザクションにいません。
関連項目