私はSqlConnection
を使用してデータベースに接続するASP.NET Web APIを持っています。私は、接続を含むインスタンス変数を持つデータアクセス層クラスを持っています。 I理由のカップルのためにこれを行う:DALクラスのコンストラクタ内の接続文字列(テストコード用など) ASP.NETにSqlConnectionを適切に配置しますか?
- 呼び出しコードAPIコントローラを開く必要が場合がありますSQL接続を開始し、トランザクションを開始してから、トランザクションをコミットする(またはロールバックする)前に、DALクラス内のいくつかのメソッドを呼び出します。だから、コネクションを開いたままにしておく必要があるため、メソッドごとにコネクションを閉じて再オープンすることはできません(また、
SqlTransaction
オブジェクトをスコープに入れておく必要があります。トランザクションはDALコール間でロールバックされます。 - これはまた、コードの読みやすさを簡素化するので、SQL接続を開くための場所全体にコードを複製しているわけではありません。
私のAPIをストレステストしたところ、毎秒何百ものリクエストを与えることで、SQL接続プールの枯渇という問題にぶつかりました。さらに調査すると、これはSQL接続が処分されていないためであると思われます。
私はIDisposable
パターンを理解していますが、このシナリオでどのように使用するかはわかりません。ここに私の問題だ:
using
ブロック、またはtry/catch/finally
ブロックを使用して、両方のは、オブジェクト、作成に使用して、単一のメソッド内で確定することが必要です。上記の例では、複数のメソッド呼び出しにまたがって持続する必要のあるトランザクションは不可能です。- マイクロソフト(およびSO上の他の記事は)単純に代わり示唆、オブジェクトのデストラクタで
Dispose()
に電話を入れて反対をお勧めしていますが、私は問題で指定されたオプションのいずれかを実行し、Microsoftはまた、あなたが実装するべきではないと言う。1. IDisposable
自分で別の管理オブジェクトのDispose
メソッドをラップするだけで済みますが、オブジェクトを終了したら「単にDispose()を呼び出す」必要があります。コントローラがSQL接続の使用を終了したときに、DALの中からわからないときは、このシナリオでどのようにしたらいいですか? (また、これはそれだけで道缶を蹴っていますので、私は、using
ブロックにDALへの各呼び出しをラップするようにコントローラをリファクタリングする必要が意味します。)
私にとって理想的なソリューションは次のようになりコントローラーが処理を終了し、サーバーへの応答をフロントエンドに渡すために返すときに、SqlConnection
オブジェクトで呼び出されたDispose
メソッドを何らかの形で整理できるようにするためです。これを「手作業で」行うには、上記のポイント3に違反し、私のDAL上に独自のDispose
メソッドを作成して、単にSqlConnectionのDispose
を呼び出す必要があります。また、すべてのコントローラで多くのメソッドをリファクタリングして、すべてのDALアクセスをusing
ブロックにラップする必要があることを意味します。コントローラが復帰したときにASP.NETが自動的にDispose
を呼び出すことはないため、接続が漏れているようです。
いずれの場合も、より冗長なコードになります。たとえば:
// we have to initialize here to keep the variable from falling out of scope after the using blocks
// we also must provide some value because the using block implies try/catch.
string someData = "";
using (DAL d = new DAL()) {
someData = d.getSomeData(someParam);
}
は何これを実装するために推奨される方法のようになります。
// we only need one method call from the DAL, so let's be compact
string someData = new DAL().GetSomeData(someParam);
今のように書かれなければなら?
より一般的なプレーンでは、メソッド呼び出し(インスタンス変数など)の間に存続する必要がある使い捨てオブジェクトを実際にどのように処理しますか? try/catch/finally
またはusing
のような構造内でディスポーザブルを使用する必要性は、オブジェクトを作成して1つのメソッド内に配置できる状況にのみ使用を制限するようです。
DIコンテナを使用している場合は、リクエストが終了したときにリソースを廃棄することができます。私は個人的にコネクションを自分で管理することを好みますが、必要なときに開いて、やってみましょう。 – Evk