次の質問に答えるのを手伝ってくれる C3P0 の専門家がいることを願っています。
まず、これが私が解決しようとしている一般的な問題です。データベースに接続されたアプリケーションがあります。データベースが停止すると、リクエストの処理に数ミリ秒ではなく、数秒かかるようになります。これは、C3P0 がデータベースへの新しい接続を作成しようとするためです。最終的にタイムアウトになり、リクエストは拒否されます。
私はそれを修正する提案を思いつきました。プールから接続を取得する前に、C3P0 の API にクエリを実行して、プールに接続があるかどうかを確認します。何もない場合は、すぐにリクエストを破棄します。このようにして、タイムアウトが発生するまで待機するのではなく、レイテンシーをミリ秒単位で維持する必要があります。このソリューションは、C3P0 が接続の不良を検出した場合に接続を削除できるため、機能します。
ここで、「setTestConnectionOnCheckin」と「setTestConnectionOnCheckout」の値を「false」にしてテストをセットアップします。私の理解によれば、これは C3P0 が接続をテストしないことを意味します (または、idleConnectionTestPeriod 設定もあるため、使用中の接続としましょう)。ただし、テストを実行すると、データベースをシャットダウンした直後に、C3P0 がそれを検出し、プールから接続を削除します。より明確な図を提供するために、実行の結果を次に示します。
14:48:01 - リクエストが正常に処理されました。処理時間: 5 ミリ秒。14:48:02 - リクエストが正常に処理されました。処理時間: 4 ミリ秒。14:48:03 - (データベースはこの時点でシャットダウンされます)。14:48:04 - java.net.ConnectException. 14:48:05 - リクエストが拒否されました。処理時間: 258 ミリ秒。14:48:06 - リクエストが拒否されました。処理時間: 1 ミリ秒。14:48:07 - リクエストが拒否されました。処理時間: 1 ミリ秒。
C3P0 は、データベースがダウンしたことを認識しており、プールから接続を削除したようです。データベースがシャットダウンされた後の最初の要求は、他の要求よりも時間がかかったため、おそらくしばらく時間がかかりました。このテストを数回実行しましたが、その 1 つの要求に 1 ミリ秒から最大 3.5 秒 (タイムアウト時間) かかる場合があります。このエントリは、プールに定義した接続の数だけ表示されます。簡単にするために、残りはすべて省略しました。
C3P0 がすぐにプールから接続を削除できるのは素晴らしいことだと思います (上記の例では 258 ミリ秒という速さです) が、他の人にそれが機能する理由を説明するのに苦労しています。「setTestConnectionOnCheckin」と「setTestConnectionOnCheckout」が「false」に設定されている場合、C3P0 はどのようにして接続が失敗したことを知ることができますか?
それらが「true」に設定されていたとしても、接続のテストは、データベースでクエリの実行を試みることになっています (「select 1 + 1 from dual」のようなもの)。データベースがダウンした場合、テストがタイムアウトになるのではないでしょうか? 言い換えれば、C3P0 が接続不良を判断するのに 3.5 秒かかるのではないでしょうか?
よろしくお願いします。