web-dev-qa-db-ja.com

プールされた接続がタイムアウトしました

本番サーバーでは、Oracleデータベースへの接続がランダムに失敗することがあります。私はたくさん得る

Oracle.DataAccess.Client.OracleException 
Pooled connection request timed out
   at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
   at Oracle.DataAccess.Client.OracleConnection.Open()
   at ws.DataConnection() in path. 



私はいくつかの解決策を探しましたが、運がありませんでした。例外にOra-123のような識別子がないのは不思議です...私はOracleDataAccessクライアントを使用しています。この問題が5〜10秒間発生する場合もあれば、問題を解決するためにIIS(6.1、Windows Server 2008 R2))を再起動する必要がある場合もあります。イライラします... pooling = falseを設定できません巨大なウェブサイトがあるからです。解決策はありますか?

12
Coder

私が知っているこの最も一般的な原因は、Oracle.DataAccess.Clientに関連付けられたIDisposableオブジェクトを適切に処理できないことです。

おそらく、いくつかのオブジェクトを適切に処理していないコードがいくつかあります。これにより、Oracleは実際には使用されていない接続を保持し、プールで使用可能な接続が不足します。 IISを再起動すると、これらの接続がすべて切断されるため、解決されます。

コードを注意深く確認し、すべてのIDisposableオブジェクトが適切に破棄されているか、usingステートメントでカプセル化されていることを確認してください。

10
Nick Zimmerman

私が見た最も一般的な接続の問題は次のとおりです。

  • アプリケーションは接続を開いたままにします。これは利用可能なすべての接続を使い果たしているため、接続はランダムに拒否されています。このための最も簡単なコードソリューションは、アプリケーションが(変数がスコープを離れるのを待つのではなく)できるだけ早く接続を閉じるようにすることです。 .NETの「using」ステートメントはこれに適しています。
  • 接続プールのリサイクルが必要になる場合があります。詳細については、このサイトを参照してください。 http://docs.Oracle.com/cd/E11882_01/Java.112/e12265/manage.htm#BABICIII
  • 十分な大きさの接続プールがない可能性があります(デフォルトの最大サイズは100です)。これを増やしてみてください。

役立つかもしれないもう1つのサイトはこれです: http://blog.ilab8.com/2011/09/02/odp-net-pooling-and-connection-request-timed-out/

4
drew_w

重要なのは、DbContextで.Dispose()を呼び出すか、コンテナが.Dispose()を呼び出していることを確認することです(disposeをオーバーライドし、新しいDbContextごとに.Dispose()への対応する呼び出しがあることを確認します)。 。

デストラクタ〜MyDbContext()を簡単なハックとして使用して、Dispose()を呼び出すと、アプリが接続を開いたままにする(つまり、DbContextでDispose()を呼び出さない)問題が修正されることを確認できます。

Oracleプロバイダーでは、[〜#〜] must [〜#〜] Disposeを呼び出す(またはコンテナが自動的に実行します)。そうしないと、接続がリーク/不足します。

必要に応じてサンプルコードを提供できますか?

2
Tod Thomson

データベースに反省的に接続していないことを確認してください。といった:

// collection to wrap several db records
private List<YourClassItems> list
get
{
    if (Session["FOO"] == null)
    {
        // this method connect to the database
        List<YourClass> lst = GetItems();
        Session["FOO"] = lst;
        return lst;
    }
    return (List<YourClass>)Session["FOO"];
}

// then we have the GetItems() method
private List<YourClass> GetItems()
{
    // get several items from database.
    while (read())
    {
        // assume this row is an item
        RowItem i = read.Row;
        // THIS might be your problem. It will recursively call this method
        yourClassItems.Add(i); 
    }

    //to solve this, create a List<YourClass> tempList and then
    //yourClassItems = tempList outside the loop
}
1
Punisher