2009-03-13 20 views
69

usingステートメントにIDbTransactionがありますが、usingステートメントで例外がスローされた場合にロールバックされるかどうかはわかりません。私はusingステートメントがDispose()の呼び出しを強制することを知っています...しかし、Rollback()に対して同じものが当てはまるか知っていますか?エラーが発生した場合、usingステートメントはデータベーストランザクションをロールバックしますか?

更新:また、以下のようにCommit()を明示的に呼び出す必要がありますか?またはusingステートメントで処理されますか?

using Microsoft.Practices.EnterpriseLibrary.Data; 

... 

using(IDbConnection connection = DatabaseInstance.CreateConnection()) 
{ 
    connection.Open(); 

    using(IDbTransaction transaction = connection.BeginTransaction()) 
    { 
     //Attempt to do stuff in the database 
     //potentially throw an exception 
     transaction.Commit(); 
    } 
} 
+3

こんにちは、ちょうど "コミット"ケースを明確にする。もちろん、using(){}はDispose()メソッドを呼び出すだけなので、必須ではありません。 Transaction.Disposeクラスは、コミットも自動的に行われた場合、コミットするかディスポージするかを知ることができませんでした。 –

+0

も参照してください。http://stackoverflow.com/questions/6418992/is-it-a-better-practice-to-explicitly -call-transaction-roll-back-or-let-an-except- – nawfal

答えて

85

どうやらはい(SQL Serverの場合):

私のコードは、一種の次のようになります。これは、(のSqlTransactionの廃棄呼び出し)SqlInternalTransactionのDisposeメソッドがReflectorからどのように見えるかです:

private void Dispose(bool disposing) 
{ 
    // ... 
    if (disposing && (this._innerConnection != null)) 
    { 
     this._disposing = true; 
     this.Rollback(); // there you go 
    } 
} 

EDIT:@MedinocはOracleConnectionは行わないことを述べたので、それは実装固有思われること。

+0

これは、明示的に例外をスローすることでこれを一度テストしました。 –

+0

それは素晴らしいです!今私の心には1つの質問がありますが、私は明示的にコミットを呼び出す必要がありますか?またはusingステートメントは、あまりにも効果的に私の現在のコミットステートメントを冗長にします。 – mezoid

+1

これは*素晴らしい*ですが、クロスdb互換性のためにIDbTransactionを使用している場合、IDbTransactionの他の実装でも機能しますか? –

4

私は、Commit()が呼び出されなかったという例外があると、トランザクションは自動的にロールバックされると私は信じています。

+0

それは私の理解です。トランザクションは、コミットが呼び出されるか、接続が終了するまで存続します。その時点で、トランザクションログは実際には変更で更新されるか、閉じた接続の場合はロールバックされます(閉じられた接続から決してコミットすることはありません)。 – Mike

17

コミットを呼び出す必要があります。 usingステートメントはあなたに何もコミットしません。

+5

はい、使用すると、終了時にDisposeが呼び出されます。コミットではなくロールバックが呼び出されます。 – awe

関連する問題