2012-06-08 44 views
17

SQL Server(2008r2)プロシージャをコーディングしていて、トランザクションでラップする場合は、明示的にtry..catchブロックに囲み、明示的にcatchブロック内でロールバックを呼び出す必要がありますかそれ自身を終了してロールバックしますか?try..catchブロックと明示的なロールバックをSQL Serverプロシージャで使用する必要がありますか?

すなわち:これはどのよう

begin transaction 

    begin try 
    delete from.... 

    insert into... 
    end try 
    begin catch 
    rollback transaction 
    return 
    end catch 

    commit transaction 

はとの比較:

begin transaction 
    delete from.... 

    insert into... 
    commit transaction 

は、任意の助けてくれてありがとう。ほとんどの場合、エラーが、すべての

あなたはすべてのエラーが

ベストプラクティスON SET XACT_ABORTで始まるトランザクションの前にするために、ロールバックを保証したい場合は、明示的にではありませんがある場合

答えて

19

あなたの質問への答えはSET XACT_ABORT設定に依存します:

は、Transact-SQLステートメントは、実行時エラーが発生すると、SQL Serverは自動的に現在の トランザクションをロールバックするかどうかを指定します。

SET XACT_ABORTがONの場合、Transact-SQLステートメントで実行時エラー が発生すると、トランザクション全体が終了してロールバックされます。

SET XACT_ABORTがOFFの場合、エラーを発生させたTransact-SQL ステートメントのみがロールバックされ、トランザクション が処理を続行する場合があります。エラーの重大度に応じて、SET XACT_ABORTがオフであってもトランザクション全体がロールバックされることがあります( )。 デフォルト設定はOFFです。

構文エラーなどのコンパイルエラーは、SET XACT_ABORTの影響を受けません。

たとえば、次のコードを試してください。最初の0で除算するとエラーが発生しますが、は実行を続行します。ゼロによる2部では、エラー手を上げ、実行を一時的に停止させます。XACT_ABORTがONの場合

begin transaction 

set xact_abort off 

select 1/0 -- causes divide by zero error, but continues 
select @@trancount -- returns 1 

set xact_abort on 

select 1/0 -- causes divide by zero error and terminates execution 
select @@trancount -- we never get here 

rollback 

、その後のエラーは、トランザクションをアボートします、そしてあなたは、TRY/CATCHを必要としません。XACT_ABORTがOFFの場合、エラーが発生した場合

、あなたは見に各ステートメントの状態を確認する必要があります。

begin transaction 

delete from... 
if @@error <> 0 
begin 
    if @@trancount > 0 
     rollback 
    return 
end 

insert into... 
if @@error <> 0 
begin 
    if @@trancount > 0 
     rollback 
    return 
end 

commit 

をしかし、あなたはあなたが/ CATCHをしようとする必要があるケースを見つけた場合、あなたにエラーが発生したときに特別な処理が必要な場合があります。その場合は、例外処理をTRY/CATCHすることを忘れないでください。

begin transaction 

set xact_abort on 

begin try 
    select 1/0 -- causes divide by zero error and terminates execution 
    select @@trancount -- we never get here 
    commit 
end try 
begin catch 
    select xact_state() -- this will be -1 indicating you MUST rollback before doing any other operations 
    select @@trancount -- this will probably be one, because we haven't ended the transaction yet 
    if xact_state() <> 0 
    begin try 
     select 'rollback' 
     rollback 

     -- do something to handle or record the error before leaving the current scope 
     select 'exception processing here' 
     --insert into... 
    end try 
    begin catch 
     -- ignore rollback errors 
    end catch 

end catch 
4

ロールバックが自動的に行われますtry-catchブロックでエラーを捕捉し、そこにアクションを起こします。おそらくロールバックやエラーの報告/ログ記録などがあります。

0

エラーの重大度によって異なります。十分に高い - 16、おそらく? - トランザクションが失敗した行で停止し、トランザクションが開かれ、がロックされ、ロックされた状態になることがあります。トランザクション内でエラーが発生する可能性がある場合は、最初の例のように、try-catchブロックにラップしてください。

関連する問題