SQL Server Books Onlineを見ると、Microsoftはストアドプロシージャでネストされたトランザクションを処理する(不正な) メソッドを持っているようです :
入れ子のトランザクション
明示的なトランザクションはネストできます。これは主に、すでにトランザクション内にあるプロセスから、またはアクティブなトランザクションがないプロセスから呼び出すことができるストアドプロシージャのトランザクションをサポートすることを目的としています。
この例では、独自のトランザクションを開始するストアドプロシージャを示します( "プロシージャは、それを実行するプロセスのトランザクションモードに関係なく、トランザクションを強制します。"):
CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS
BEGIN TRANSACTION InProc
...
COMMIT TRANSACTION InProc;
このプロシージャは、トランザクションを実行せずに呼び出すことができます。
EXECUTE TransProc 3,'bbb';
または、with明示的なトランザクション:
BEGIN TRANSACTION OutOfProc;
EXEC TransProc 1, 'aaa';
COMMIT TRANSACTION OutOfProc
彼らが対処していないのは、格納されたプロシージャが次の場合に何が起こるかです。
ありません:
SET XACT_ABORT ON
標準的な例のどこでも。
もっとよくわからなければ、次のように考えていました。
次の例は、ネストされたトランザクションの使用目的を示しています。
実際に読むべき
次の例は、ネストされたトランザクションを使用しない方法を示しています。
誰かがこのBOLの例の表または裏を作成できない限り、
トランザクションでtry catchブロックを使用する必要があります。したがって、catchブロックでエラーが発生した場合は、トランザクションをロールバックできます。
これについては、以下のSQLサーバーコードを参照してください。
BEGIN TRANSACTION;
BEGIN TRY
-- Some code
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH;
CREATE PROCEDURE [usp_my_procedure_name]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @trancount int;
SET @trancount = @@trancount;
BEGIN TRY
IF @trancount = 0
BEGIN TRANSACTION
ELSE
SAVE TRANSACTION usp_my_procedure_name;
-- Do the actual work here
lbexit:
IF @trancount = 0
COMMIT;
END TRY
BEGIN CATCH
DECLARE @error int,
@message varchar(4000),
@xstate int;
SELECT
@error = ERROR_NUMBER(),
@message = ERROR_MESSAGE(),
@xstate = XACT_STATE();
IF @xstate = -1
ROLLBACK;
IF @xstate = 1 AND @trancount = 0
ROLLBACK
IF @xstate = 1 AND @trancount > 0
ROLLBACK TRANSACTION usp_my_procedure_name;
RAISERROR ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message);
END CATCH
END