2017-01-04 3 views
0

私のコードからストアドプロシージャを呼び出しています。ストアドプロシージャを呼び出す前に、私は接続が開いているかどうかを確認しています。そうでない場合は、接続を開きます。トランザクションの名前を付けるときに@@計数が必要ですか?

ストアドプロシージャは、次の体を持っています

begin try 
    begin tran mytran; 

    --do inserts here into my table 

    commit tran mytran; 

    --return id''s of inserted records 
    select id from mytable; 
end try 
begin catch 
    rollback tran mytran; 
    throw; 
end catch; 

トランザクションを明示的に、ストアドプロシージャで開始されました。上記は正しいですか私が使用する必要があります。

begin catch 
    if @@trancount > 0 
    rollback tran mytran; 

    throw; 
end catch; 

第二に、最終select id from mytable;場所が正しいか、それはend catchブロックの下に移動する必要がありますか?

+0

あなたがイスラエルの墓地に戻ってくるのを手に入れたいなら、それを「エンドキャッチ」の下に置く。なぜなら、インサートやその他の何かが失敗したとしても、あなたは引き続きIDの背中を得るからです。私はあなたがこれをどのように扱うかを知らない。しかし、失敗があった場合、それを見るのは難しいです。あなたがあなたのブロックの終わりにそれを置くと失敗すると、あなたは "間違った" IDを取得しません。あなたの2番目の質問:TRY ... CATCHコンストラクトは、データベース接続を閉じない重大度が10以上のすべての実行エラーをキャッチします。だから私はあなたのように2回私を救い、 'if @@ trancount> 0'をインスタントロールバックの代わりに配置します。 – Cataklysim

答えて

0

まず、明示的なトランザクションを持つストアドプロシージャにSET XACT_ABORT ON;を追加することをお勧めします。これにより、クエリのキャンセルまたはタイムアウト後にトランザクションがロールバックされ、catchブロックが実行されずトランザクションがコミットされないままになることが保証されます。

セーブポイントを使用しない限り、ROLLBACKに指定されたトランザクション名は不必要です。この場合、セーブポイントがない場合は、トランザクション名を省略します。セーブポイントを持たないROLLBACKは、トランザクション名がSQL Server Books Onlineに従って指定されているかどうかにかかわらず、すべてのトランザクションをロールバックします。

ブロックの末尾にTRYブロックがある場合、結果セットは成功した場合にのみ返されます。COMMIT;エラーが発生した場合、結果セットは返されません。

ROLLBACKの前に@@ TRANCOUNTをチェックして、セッションのXACT_ABORT設定に関係なくコードが機能するようにすることをおすすめします。

CREATE PROC dbo.Insert_MyTable 
AS 
SET XACT_ABORT, NOCOUNT ON; 
BEGIN TRY 
    BEGIN TRAN mytran; 

    --do inserts here into my table 

    COMMIT TRAN mytran; 

    --return id''s of inserted records 
    SELECT id FROM mytable; 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 ROLLBACK; 
    THROW; 
END CATCH; 
GO 
関連する問題