web-dev-qa-db-ja.com

BEGIN / END TRANSACTION内でストアドプロシージャを実行する

SQLでストアドプロシージャを作成して呼び出した場合(EXEC spStoredProcedure)BEGIN/END TRANSACTION内で、この他のストアドプロシージャもトランザクションに該当しますか?

C#でtry/catchesのように機能するかどうかは知りませんでした。

37
Miles

はい、すべてトランザクションの開始とコミット(またはロールバック)の間に行うことは、トランザクションの一部です。

40
Blorgbeard

すばらしいですね、ありがとう。私はこのようなことをしました(私は05だからです)

    BEGIN TRY
       BEGIN TRANSACTION

       DO SOMETHING

       COMMIT
    END TRY
    BEGIN CATCH
      IF @@TRANCOUNT > 0
         ROLLBACK

      -- Raise an error with the details of the exception
      DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
      SELECT @ErrMsg = ERROR_MESSAGE(),
             @ErrSeverity = ERROR_SEVERITY()

      RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH
12
Miles

クリスが述べたように、トランザクションのロールバックには注意が必要です。

具体的にはこれ:

IF @@TRANCOUNT > 0 ROLLBACK

常にあなたが望むものではありません。このようなことができます

IF(@@TRANCOUNT = 1) ROLLBACK TRAN
ELSE IF(@@TRANCOUNT > 1) COMMIT TRAN
RETURN @error

このようにして、呼び出し側のプロシージャは、ストアドプロシージャからの戻り値を検査し、とにかくコミットするか、エラーをバブルアップし続けるかを決定できます。

その理由は、「COMMIT」はトランザクションカウンターをデクリメントするだけだからです。トランザクションカウンターをゼロまでデクリメントすると、実際のコミットが発生します。

5
James

Chris および James が述べられているように、ネストされたトランザクションを扱うときは注意する必要があります。 Don Peterson on SQL Server Centra lによって書かれたトランザクションのテーマに関する非常に良い記事があります。それらを読むことをお勧めします。

ここにあります:

2
kristof

@クリス、私はそれを知りませんでした。

詳細を探してみると、 this -トランザクション全体をロールバックせずにロールバックできる「セーブポイント」を設定できます。

この状況で役立つ可能性があります。

1
Blorgbeard

はい、ネストされたストアドプロシージャコールはすべて、トランザクションのスコープに含まれます。 SQL Server 2005以降を使用している場合は、Try ... Catchも使用できます。 ここ はその詳細です。

1
Ben Hoffstein