2009-04-20 4 views
0

を実行します。このコードは、データベースを介して実行された場合トランザクション数は後に、私は何かのように見えますストアドプロシージャ持っエラー


CREATE PROCEDURE my_procedure 
    @val_1 INT, 
    @val_2 INT 
AS 
SET NOCOUNT ON; 
SET XACT_ABORT ON; 

BEGIN TRY 
    BEGIN TRANSACTION; 

    INSERT INTO table_1(col_1, col_2) 
    VALUES (@val_1, @val_2); 

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

    DECLARE 
    @ERROR_SEVERITY INT, 
    @ERROR_STATE INT, 
    @ERROR_NUMBER INT, 
    @ERROR_LINE  INT, 
    @ERROR_MESSAGE NVARCHAR(4000); 

    SELECT 
    @ERROR_SEVERITY = ERROR_SEVERITY(), 
    @ERROR_STATE = ERROR_STATE(), 
    @ERROR_NUMBER = ERROR_NUMBER(), 
    @ERROR_LINE  = ERROR_LINE(), 
    @ERROR_MESSAGE = ERROR_MESSAGE(); 

    RAISERROR('Msg %d, 
    Line %d, 
    :%s', 
    @ERROR_SEVERITY, 
    @ERROR_STATE, 
    @ERROR_NUMBER, 
    @ERROR_LINE, 
    @ERROR_MESSAGE); 
END CATCH 

を、すべてが正常に動作します。 『テーブル『dbo.table_1』、列『col_1』を

FK_table1_table2「FOREIGN KEY制約と競合INSERT文は」my_database」競合がデータベースで発生しました。』:ADO.NETを通じて実行すると私は戻って、次のエラーメッセージが表示されます以前のカウント= 1、現在のカウント= 0 "

の設定により、ADO.NETからのトランザクションを強制的にロールバックするため、この問題が発生しているかどうかを確認します。 ?このエラーを避ける最善の方法は何ですか?

答えて

2

、あなたのコード内でXACT_STATE()をチェックし、コミットまたはロールバック、ここでそれをチェックアウトすることができます:Use XACT_STATE() To Check For Doomed Transactions

基本的にこのような何かが

BEGIN TRANSACTION TranA 
    BEGIN TRY 
    DECLARE @cond INT; 
    SET @cond = 'A'; 
    END TRY 
    BEGIN CATCH 
    PRINT 'a' 
    END CATCH; 
    COMMIT TRAN TranA 

を爆破し、あなたがxact_stateをチェックするときにすることができそれは

BEGIN TRANSACTION TranA 
    BEGIN TRY 
    DECLARE @cond INT; 
    SET @cond = 'A'; 
    END TRY 
    BEGIN CATCH 
    PRINT ERROR_MESSAGE(); 
    END CATCH; 
    IF XACT_STATE() =0 
    BEGIN 
    COMMIT TRAN TranA 
    END 
    ELSE 
    BEGIN 
    ROLLBACK TRAN TranA 
    END 

またリンク Implementing Error Handling with Stored Proceduresとを読まなければならないこれら二つを見てみましょう制御。

+0

TRY/CATCHエラー処理を実行している場合、より良いアプローチはsprocsでXACT_ABORTを使用しないことでしょうか? –

+0

XACT_ABORTは、残っているジャンクを解消し、分散トランザクションを実行するときにも必要となるため、常に使用することをお薦めします。読んでいただけるように2つのリンクを追加します – SQLMenace

2

IF XACT_STATE()= 0 ERROを生成するTRAN TranA END

をCOMMIT BEGIN。 = XACT_STATE())0(

XACT_STATEをコミットまたはロールバックするトランザクションが存在しないことを意味= 1 -1 =コミット可能トランザクション)は

XACT_STATE(ある意味するデータベースエンジンによってロールバックされるuncommitableトランザクションが存在することを意味します現在の文脈の終わりに。

関連する問題