6

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

遅延ロードを使用したため、データコンテキストでDisposeを使用しません。いくつかの記事とブログ投稿は、これは問題ではないはずだと言っています。

それでも、これらの例外が発生することがあります。ただし、接続を開いたままにするすべてのlinqクエリであるとは限りません。そうすると、さらに多くの例外が発生します。

編集済み

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

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

4

3 に答える 3

11

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

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

このためのドキュメントはあいまいであり、ほとんどの場合、DataContextを破棄せずに済ませることができますが、接続からロードされたデータが接続自体を維持しているシナリオもあるようです。あなたのケースでこれが起こっていることを確認する最も簡単な方法は、それをテストすることです。

于 2009-04-23T06:16:21.113 に答える
4

さらに検索したところ、この質問と回答が見つかりました。ここでは、linqをだまして接続を開いたままにしておくことができると書かれています。

私はそれを再現するこの小さなテストコードを作成しました。列挙子をforeachに置き換えるだけで正常に機能しますが、列挙子は接続を開いたままにします。

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;
}

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

于 2009-04-23T07:30:57.940 に答える
0

データベースにデッドロックが発生していますか?アクティビティモニターをざっと見ると、いくつかの指標が得られるはずです。

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

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

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

于 2009-04-23T06:15:14.533 に答える