2009-04-23 12 views
6

LINQを使用しているときにsql接続リークを取得することはできませんでしたが、NumberOfReclaimedConnectionsのperfmonトレースは高い数値を示し、高負荷では「タイムアウトの期限切れ」などの例外が発生することがあります。これは、プールされたすべての接続が使用されていて、最大プールサイズに達したために発生した可能性があります。LINQを使用してSQL接続リークを取得できますか?

私たちはデータ読み込みを使用しているため、データコンテキストには使用しません。いくつかの記事とblogpostは、これは問題ではないと私に伝えています。

なお、これらの例外が発生することがあります。しかし、私たちが行うすべてのlinqクエリが接続を開いたままにしておくことはできません。そうすれば、さらに多くの例外が発生します。

編集済み

アプリケーションはWCFサービスです。

Linqとほとんどの記事のドキュメントを見ると、Disposeは接続を解放する必要はないと主張しています。 DataCOntextは、必要な短い時間だけ接続を開いたままにしておくと主張しています。

答えて

8

あなたのDataContextが処分されておらず、生き続けると、関連する接続も生き残ります。データベース接続は管理されていないリソースであり、すべての管理対象外のリソースは適切に処分されている必要があります。

遅延ロードを使用していてもスコープが定義されていない場合でも、論理作業単位の最後にデータベース接続をクリーンアップする必要があります。 ASP.NETアプリケーションでは、要求処理の最後、つまりGlobals.asaxファイルのApplication_EndRequestメソッドで、これが可能な最新の瞬間があります。 WCFサービスでは、すべてのアクティブなデータコンテキストをすべてのサービスメソッド呼び出しの最後に処理する必要があります。

これに関するドキュメントはあいまいですが、ほとんどの場合、DataContextを廃棄しないと、接続から読み込まれたデータが接続自体を有効に保っているシナリオがあるようです。これがあなたのケースで起こっていることを確認する最も簡単な方法は、それをテストすることです。

+0

ニース。ありがとう:) –

0

データベースにデッドロックがありますか?アクティビティモニターを見てみると、何か指示が出ます。

DataContextのライフサイクルを管理するために何をしますか?どのような種類のアプリケーション(Webサイト、Windowsクライアント、その他)を作成しましたか?

一度クエリまたは操作で使用されると、DataContextはロードされたエンティティが遅延ロード&などをロードできるように接続を維持するため、アプリケーションでDataContextを使用する方法を計画することが不可欠です。

WCFサービス..その場合、私は「1つのコンテキストごとの1つのコンテキスト」アプローチの大きなファンです。私は、データ操作をusing()ステートメント内にラップして、完了後にコンテキストが破棄されるようにすることをお勧めします。

+0

デッドロックには問題はありません。少なくとも私が今知っているように私はそれを監視しています。 アプリケーションはWCFサービスであり、datacontextは決してサービスコールより長く生きてはなりません。 – Atle

4

いくつかは、より検索した後、私はそれがLINQは接続を開いたままにするだまされることを述べているこのquestion and answerを、見つけた。..

私はそれを再生し、この小さなテストコードを作りました。私がちょうどforeachでEnumeratorを置き換えればうまく動作しますが、Enumeratorは接続を開いたままにします。

public Organisation RunTestQuery2() 
{ 
    IEnumerable<Organisation> orgs = base.GetEntities<Organisation>().Take(5); 

    var enumerator = orgs.GetEnumerator(); 
    int i = 0; 


    while (enumerator.MoveNext()) 
    { 
     var org = enumerator.Current; 
     Debug.WriteLine(org.DescribingName); 
     if (i == 3) 
     { 
      return org; 
     } 
     i++; 
    } 

    return null; 
} 

コンテキストにdisposeする呼び出しを追加すると、それらは消えます。

+0

それはちょうどコンパイラの魔法です。 foreachは、列挙子をインスタンス化し、それがfalseを返すまでMoveNextを呼び出し、次に列挙子でDisposeを呼び出すためのシンタックスキャンディです。ちょうどFYI。 – Kilanash

関連する問題