sql >> データベース >  >> RDS >> Sqlserver

TRY CATCH ROLLBACK パターンを含むネストされたストアド プロシージャ?

    これは私たちのテンプレートです (エラー ログは削除されています)

    これは処理するように設計されています

    説明:

      <リ>

      @@TRANCOUNT になるように、すべての TXN begin と commit/rollbacks をペアにする必要があります。 入口と出口は同じです

      <リ>

      @@TRANCOUNT の不一致 エラー 266 の原因

        <リ>

        BEGIN TRAN インクリメント @@TRANCOUNT

        <リ>

        COMMIT デクリメント @@TRANCOUNT

        <リ>

        ROLLBACK @@TRANCOUNT を返します ゼロへ

      <リ>

      @@TRANCOUNT を減らすことはできません 現在のスコープに対して
      これが「内部トランザクション」と思われるものです

      <リ>

      SET XACT_ABORT ON @@TRANCOUNT の不一致によるエラー 266 を抑制します
      また、この "SQL Server トランザクション タイムアウト" のような問題にも対処します dba.se

      <リ>

      これにより、クライアント側の TXN (LINQ など) が可能になります。単一のストアド プロシージャは、分散トランザクションまたは XA トランザクションの一部である場合もあれば、クライアント コードで開始された単なるストアド プロシージャ (.net TransactionScope など) である場合もあります。

    用途:

    • 各ストアド プロシージャは同じテンプレートに準拠する必要があります

    まとめ

    • したがって、必要以上の TXN を作成しないでください

    コード

    CREATE PROCEDURE [Name]
    AS
    SET XACT_ABORT, NOCOUNT ON
    
    DECLARE @starttrancount int
    
    BEGIN TRY
        SELECT @starttrancount = @@TRANCOUNT
    
        IF @starttrancount = 0
            BEGIN TRANSACTION
    
           [...Perform work, call nested procedures...]
    
        IF @starttrancount = 0 
            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        IF XACT_STATE() <> 0 AND @starttrancount = 0 
            ROLLBACK TRANSACTION;
        THROW;
        --before SQL Server 2012 use 
        --RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
    END CATCH
    GO
    

    注:

      <リ>

      SET XACT_ABORT ON のため、ロールバック チェックは実際には冗長です。 .しかし、気分が良くなり、ないと奇妙に見え、つけたくない状況にも対応できます

      <リ>

      レムス・ルサヌ 同様のシェル を持っています セーブポイントを使用するもの。アトミック DB 呼び出しを好み、記事のような部分更新は使用しません



    1. mysql_escape_stringポスト配列全体?

    2. PHP + MySQL CMSを自己更新する方法は?

    3. Sql Server 2005 でテーブル型を作成する方法

    4. SQLAlchemyでENUMを作成するにはどうすればよいですか?