私は自分のコードで使用しているSqlTransactionに関するいくつかの問題に直面しています。グーグルで調べている間に、SqlTransactionでusingステートメントを使用している人がたくさんいます。
このタイプのステートメントをSqlTransactionで使用することの利点および/または違いは何ですか?
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
現在、私のコードは次のようになっています。
SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"]);
cn.Open();
SqlTransaction tr = cn.BeginTransaction();
try
{
//some code
tr.Commit();
cn.Close();
}
catch(Exception ex)
{
tr.Rollback();
cn.Close();
throw ex;
}
ある方法が他の方法より優れている点は何ですか?
using
ブロックのスコープ内を実装するクラスのインスタンスを作成するたびに、IDisposable
ステートメントを使用する必要があります。例外がスローされるかどうかに関係なく、そのインスタンスでDispose()
メソッドが確実に呼び出されます。
特に、コードはマネージ例外のみをキャッチし、既存の例外を再スローする代わりに新しい例外をスローすることでスタックフレームを破棄します。
正しい方法は次のとおりです。
_using (SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"])) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction()) {
//some code
tr.Commit();
}
}
_
クラスにIDisposable
を実装する型のインスタンスメンバーがある場合、クラスはIDisposable
自体を実装し、独自のDispose()
呼び出し中にそれらのメンバーを破棄する必要があることに注意してください。
これは、SqlTransactionオブジェクトが明示的にコミットされなかった場合(例外がスローされた場合など)に、Dispose()メソッドでロールバックするためです。つまり、コードと同じ効果があり、ほんの少しだけきれいになります。
結局、using
は単なるパターンのショートカットです。しかし、これは非常に有用なであり、便利なショートカットです。パターンを正しく実装し、より少ないコードで実行できることを意味するためです。
この場合、パターンを正しく実装していません。 tr.RollBack()
への呼び出しも例外をスローした場合、コードはどうなりますか?
sing文 は、接続とトランザクションを閉じて破棄します。破棄を行うtry/catchにfinallyブロックを設定するのと同じです。
また、このように使用ブロックを少し圧縮することもできます...
using (SqlConnection cn = new SqlConnection())
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
これは次とほぼ同じです。
SqlConnection cn = null;
SqlTransaction tr = null;
try
{
cn = new SqlConnection());
tr = cn.BeginTransaction());
//some code
tr.Commit();
}
finally
{
if (cn != null)
cn.Dispose();
if (tr != null)
tr.Dispose();
}
Using()ブロックを使用しない場合、SqlConnectionおよびSqlTransactionオブジェクトの.Dispose()メソッドを明示的に呼び出す必要があります。そうしないと、管理されていないリソースは解放されず、メモリリークやその他の問題が発生する可能性があります。
それに加えて、コードをきれいにします。 7行のコードは、14行よりも見栄えがよくありませんか?使用ブロックを見るたびに、私は安心のサインを吸います。それはそのうれしい臭いものから出てくる霧の小さな噴出のようなものです。うーん、私はかなり効率的なコードのブロックです。私がどれほどうまくメモリを管理しているか、そして私がどれほど楽しいかを見てください。
を使用して、コードが戻った後に接続オブジェクトが破棄されることを保証します。 Disposeは、管理されていないリソースを解放するのに役立ちます。グッドプラクティスとして、オブジェクトがIDisposableを実装する場合、disposeメソッドを常に呼び出す必要があります。
Usingステートメントは、リソースを適切に処理するための略記です。詳細については、 ステートメントの使用に関するMSDN記事 を参照してください。