- ベストアンサー
JSPでブラウザ終了時にPostgreSQLと切断
JSP、PostgreSQLでシステムを構築しています。 JSPでPostgreSQLに接続し、更新や参照などはまったく問題ありません。 データベースに接続したら、接続した内容をインスタンス化し、Sessionレベルで情報を保つようにしています。 ページが変更しても再接続する必要がないためです。 問題は、ブラウザを閉じたときに接続が残ってしまう状況です。 PostgreSQLで、pg_stat_activityを参照すると、ブラウザが閉じても残っているのです。 同時接続数は32(デフォルト)の状態なので、何度か起動されるとすぐに「Too many client」エラーが出てしまいます。 どうにか打開策はないでしょうか? よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
コネクションプーリングは使用していますか? 普通はServlet(JSP)から直接RDBMSにJDBC接続するような 使い方はしません。 (それは教科書での話であって、実用的ではありません。) コネクションプーリングを利用すればいいと思います。 参考URLは知らないので書きませんが検索エンジンを使って検索してみてください。 参考書籍は挙げておきます。 「コア・サーブレット&JSP」 ためになると思います。
その他の回答 (2)
> そのオブジェクトがブラウザが閉じて後も生きてるのでしょうか?(そんなことはないと思いますが・・・) HTTPセッションのオブジェクトは、サーバ側に作られます。 クライアントのブラウザに対しては、このサーバ側のセッションオブジェクトに アクセスするためのIDのみが保存されます。 このため、クライアントでブラウザを閉じても、セッションオブジェクト自体は 削除されません。 また、セッションはクライアントのブラウザのプロセスごとに作られるので 今の場合、クライアントが複数のブラウザを起動すると、やはりデータベース へのコネクションが減っていくはずです。。。 # IEとかで、「新しいブラウザで開く」とかを使うと、同じプロセスで # 動くので、セッションは1つしか作られないんですが・・・ > 問題はブラウザを閉じても接続が残ることです。 今は、どのタイミングでデータベースへのコネクションを切断しているんでしょう? 質問を見ると、コネクションはオープンされたままずっと残っているようです。 このままだとセッションが残るとか、ブラウザを閉じられるせいとかいう以前に、32以上の ブラウザからアクセスがあった段階でアウトですね。。。 対策としては、最初に示したとおり、JSP内で必ずコネクションの切断を 行うようにするか、No.2 でもご指摘されている通り、コネクションプーリングを 実装したAPサーバ(or Servlet Engine)を使う/自前で実装する のいずれかです。 コネクションプールについては、参考URLで簡単に説明がされていますので、 参考にしてみてください
お礼
> このままだとセッションが残るとか、ブラウザを閉じられるせいとかいう以前に、32以上の > ブラウザからアクセスがあった段階でアウトですね。。。 確かにそうですね。 コネクションプーリングで対応しました。 ありがとうございました。
> 接続した内容をインスタンス化し、Sessionレベルで情報を保つようにしています。 > ページが変更しても再接続する必要がないためです。 この処理がよく分からないのですが、これはオープンしたデータベースの オブジェクト自身をセッションに格納しているのでしょうか? それとも、単純にデータベースで取得した内容をセッションに保持しているだけ なんでしょうか? 単純にデータベースの内容をセッションに格納しているだけであれば、 例えばJSPのコード全体をtry節で囲み、finally節でデータベースをクローズ してやれば、正しく接続を切断できると思います。 <% try { // データベースのオープン // データベースからデータを取り出す等の処理 %> <html> HTMLとして表示する部分 </html> <% } finally { // データベースのクローズ } %> セッションにデータベースのオブジェクト自体を入れているような場合には、 少なくともセッションオブジェクトが生きている間はずっとデータベースの 接続が残ったままになりますから、セッションタイムアウトまでの時間を 短くして、セッションが破棄されるときにデータベースをクローズするような コードを記述するか、データベースプーリングを使って、プール数を32以下に することで打開できると思うんですが。。。 # ただし、セッション破棄のタイミングをどうやって認識するのか # 分かりませんが。
補足
> セッションにデータベースのオブジェクト自体を入れているような場合には、 この方法になります。 > 少なくともセッションオブジェクトが生きている間はずっとデータベースの > 接続が残ったままになりますから、セッションタイムアウトまでの時間を そのオブジェクトがブラウザが閉じて後も生きてるのでしょうか?(そんなことはないと思いますが・・・) 問題はブラウザを閉じても接続が残ることです。 > 短くして、セッションが破棄されるときにデータベースをクローズするような > コードを記述するか、 この方法を考えたのですが、JavaにはC++のようなデストラクタがないですよね。 ファイナライザはあるけど、ガーベッジコレクタと同期してるから必ず動くとは限らないようです。 > データベースプーリングを使って、プール数を32以下に > することで打開できると思うんですが。。。 この方法はPostgreSQLでの手法なのでしょうか? 何か情報があれば教えてください。
お礼
> コネクションプーリングは使用していますか? この方法は使用していませんでした。 教科書どおりの方法を使っていました。(^^; 検索でいろいろと出てきましたので、参考にして改良しました。 ありがとうございました。