エラーが発生した場合、usingステートメントはデータベーストランザクションをロールバックしますか?


83

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

更新:また、以下のように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クラスは、コミットする必要があるのか​​、コミットも自動である場合は
破棄するの

回答:


104

トランザクションクラスのDisposeメソッドはロールバックを実行しますが、Oracleのクラスは実行しません。したがって、トランザクションの観点からは、実装に依存します。

using一方、接続オブジェクトのステートメントは、データベースへの接続を閉じるか、リセット後に接続をプールに返します。いずれの場合も、未処理のトランザクションはロールバックする必要があります。そのため、例外によってアクティブなトランザクションが放置されることはありません。

また、はい、Commit()明示的に呼び出す必要があります。


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

1
それ素晴らしいことですが、データベース間の互換性のために使用している場合、IDbTransactionの他の実装でも機能しますか?
マットハミルトン

4
@mezoid:コミットが自動的に行われることはありません。@matt:設計上、そうすべきです。
セダットカパノグル2009年

1
@MattHamiltonはssgが言ったとおりです。MySQLの.netコネクタソースを確認しましたが、上記と同じように動作しました。Rollbackで呼び出されDisposeます!:)
nawfal 2013

1
を使用している場合System.Data.OracleConnection、破棄時にロールバックされません。または、少なくとも、私たちにとってはそうではありません。
Medinoc 2017

20

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


5
はい、を使用すると、終了時にDisposeが呼び出され、CommitではなくRollbackが呼び出されます。
畏敬の念

4

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


ええ、それは私の理解です。トランザクションは、コミットが呼び出されるか、接続が終了するまで存続します。その時点で、トランザクションログは実際に変更で更新されるか、接続が閉じられた場合はロールバックされます(閉じられた接続からコミットが取得されることはありません;))。
マイク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.