- PR -

セッションに登録したコネクションオブジェクトの接続プールへの返却方法について

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-29 15:28
引用:

忍者鳥取県さんの書き込み (2003-08-29 14:59) より:
うーん、、ようするにフラグを立てればウィンドウが閉じたことを
感知させれるのでは!?ちがうんでしょうか?


どのようなフラグをお考えでしょうか?

また、クライアントの予期せぬシャットダウンは常にあるものと考えないとまずいと思います。
(前のレスの繰り返しのような内容で申し訳ありません。)

# 全く環境は違いますので、そのまま当てはめることはできませんが、魔法の杖シンドローム
# に近いような気が・・・。
http://www.atmarkit.co.jp/fdotnet/opinion/kawamata/2002_07.html

# 追記です。
もし、大量のデータのやりとりをしなければならない場合は、リッチクライアント技術を
使って、一度該当データをクライアントに送って一旦オフライン処理したほうがBetterでは
ないか、と考えます。

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-08-29 15:39 ]
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-08-29 15:55
引用:

忍者鳥取県さんの書き込み (2003-08-29 14:59) より:
うーん、、ようするにフラグを立てればウィンドウが閉じたことを
感知させれるのでは!?ちがうんでしょうか?

(たしかに処理をJavaScriptに依存させるのは問題だと思いましたが・・)


 だから、そう言ってますよね。
でも提示されたソースはそうはなっていませんでしたね。
(だから理解していないと言ったのですよ。)
フラグを立てるにしても、その制御はどのようにしますか?
「言うは易し、行うは難し」ですね。

 私はせいぜい、終了ログの出力ぐらいにしか、こんなことしてませんが。
まりり
ぬし
会議室デビュー日: 2001/12/05
投稿数: 329
投稿日時: 2003-08-29 16:40
極端なものの言い方をすれば、HTMLやJavaScriptがブラウザの上で動くものである限り
ブラウザを閉じようとする動作に対してHTMLやJavaScriptのイベントなんてものは
起こせません。
なので、苦労するのです。


引用:

たとえば何百万件のデータをセッションに保持することになった場合
結果をセッションに登録すると相当リソースを消費してしまうような気がする
のですが、、そのWebアプリケーションを使用する人間が数人程度だったら
問題ないかもしれませんが、、、。


その何百万件のデータが本当に必要なのかをまず判断しましょう。

当然、こういう作りのアプリを何人もで使えばひどくメモリを消費しますから
何かしら手を打つ必要はあります。
が、コネクションをセッションに突っ込むということがその解決になるとは
考えられないですよ。

ページングしたいだけならちょっとSQLを工夫すればよいです。
その工夫ができないのであれば、単なるファイルをキャッシュとして
使うことだってできます。


どちらにも共通しているのは、WebアプリはVBなどで作るクライアントアプリとは
性質が違うということです。
イベントもライフサイクルも複雑になってます。
さまざまな制約を設けることで、通常のアプリにはないメリットを享受している
わけで、作りの部分でそれを意識しなければいけません。
Hush
会議室デビュー日: 2002/04/23
投稿数: 13
投稿日時: 2003-08-29 17:08
引用:

忍者鳥取県さんの書き込み (2003-08-29 14:59) より:
うーん、、ようするにフラグを立てればウィンドウが閉じたことを
感知させれるのでは!?ちがうんでしょうか?

(たしかに処理をJavaScriptに依存させるのは問題だと思いましたが・・)


[ メッセージ編集済み 編集者: 忍者鳥取県 編集日時 2003-08-29 15:03 ]



フラグで管理すれば言いと仰いますが、どう実装するのか実際に検討してみましたか?
これまでの説明から考えると、それを実現するためには下記のようなロジックを採用するしかないと思われます。

1.画面が読み込まれた際に、まだGETもPOSTも行われていないと言うフラグを立てておく。
2.GETもしくはPOSTが呼び出された際に、フラグの値を更新する。
3.onUnloadイベントの発生時に、フラグを見てWindowが閉じられようとしているのかどうか判断する。

つまり、アプリケーション中のすべてのリンクもしはサブミットからJavaScriptを呼び出す必要があります。
どう考えても開発効率の良い手法とは思えません。

またJavaScriptにクリティカルな処理を行わせるべきではないと言うのは、前述の方々の仰る通りと思います。

セッションにConnectionを保持することはそこだけ見ると便利に思われるかもしれませんが、全体を見るとけしてそうとはいえないと思います。

また、全く異なる観点からもそう言った設計はいい選択肢だとは思えません。
現在Webアプリケーションを作成する際、ある程度以上の規模では多層アーキテクチャを採用するのが一般的だと思われます。
システムを複数のレイヤーとして捉える際に、どういったレイヤーを用いて捉えるかは多くの選択肢があるかとは思います。
しかし、少なくともHttpセッションはUIを実装するレイヤーのいずれかに属する要素技術であると考えられます。
逆にConnectionはどう考えてもUI層に属するものとは思えません。
そう言った意味でもConnectionをセッションに直接保持するような設計は適切であるとは私にはとても思えません。

StrutsにはJDBC呼び出しを行うようなカスタムタグが用意されていますが、上記に近い理由から多くの批判の的にもなっています。
プレゼンテーションロジックとビジネスロジックは分離して設計・実装を行うべし、と言うのは、もはや常識だと考えています。

そんなわけで、皆さんが提案されているような別の手段を利用することを強力にお勧めします。



[ メッセージ編集済み 編集者: Hush 編集日時 2003-08-29 17:11 ]

[ メッセージ編集済み 編集者: Hush 編集日時 2003-08-29 17:12 ]
佐々木
大ベテラン
会議室デビュー日: 2003/03/30
投稿数: 121
投稿日時: 2003-08-31 14:29
ちょっと本筋から離れますが、
引用:

小手先の技で高速化した気分になるよりも、普通に検索した方がずっと
速くて安定していることもよくあると思いますよ。


これ、確かにそうですよね。DBアクセスに限らず、プログラミング全般にいえることだと思います。パフォーマンスを意識した(つもりの)小賢しいコーディングは、保守がしづらいだけでメリットがないことが多いです。

あと、話は変わりますが。
引用:

あと、いわゆる半角カナはWebでは使わない方が良いです。


なぜですか?別に良いんじゃないですか。

[ メッセージ編集済み 編集者: サ 編集日時 2003-08-31 14:30 ]
まりり
ぬし
会議室デビュー日: 2001/12/05
投稿数: 329
投稿日時: 2003-09-01 01:20
引用:

あと、話は変わりますが。
引用:

あと、いわゆる半角カナはWebでは使わない方が良いです。


なぜですか?別に良いんじゃないですか。


別に良い理由を逆に教えてください。

今となってはあまり気にすることはないかも知れませんが、
苦労する文字コードがらみで話をややこしくするのが
半角カナだと思いますよ。
Webではたいていクライアントの環境を限定できないわけで、
文字コードの自動判別が統計的な手段でしかない以上は
話を単純にさせてくれという作り手側の思いがあります。

ちなみに、私はこの時代になってまであえて半角だの全角だの
ユーザに強要するのは作り手側の怠慢だと思ってます。
ただ、苦労はわからないでもないので、昔から問題を引き起こした
ようなことはわざわざやらないほうがいいのではとは思います。
忍者鳥取県
ベテラン
会議室デビュー日: 2003/08/28
投稿数: 61
お住まい・勤務地: リオネジャネイロの地下6000Km
投稿日時: 2003-09-01 17:20
引用:

public void valueUnbound (HttpSessionBindingEvent event) {
 HttpSession hs = event.getSession();
Connection conn = (Connection) hs.getAttribute("conn");
if (conn != null) {
 try {
 conn.close();
}catch (SQLException sqle) {
System.err.println(sqle.getMessage());
}
 conn = null;
}
 System.out.println("valueUnBound");
}
コーディングを間違えているようには思えないんですが
原因が分らないのでどなたか原因がお分かりでしたら
ご指摘お願いします。



 うほほほほ
 いままで色々協力してくれた皆様方まことにありがとう
 ございました。 m(_ _)mペコリ
 な・・なんと!!! 
 スレッドの題目に書いていた内容が!! 
 解決しました!!! (・_・、)(感涙)

 まず、最初のコーディングがうまくいかなかった理由なのですが、
 public void valueUnbound (HttpSessionBindingEvent event)のメソッドは
 セッションからgetAttributeできなようになった後で呼びだされるため
 当然 Connection conn = (Connection) hs.getAttribute("conn") 
 みたいなことはできません。

 じゃーどうするかといいますとおおおお。
 次のよーなコーディングを行うことによりその問題を解決できるっぽいです。
 ってか おれも早くきづけよってな感じの内容です・・・(T▽T)オロロ

 public class SessionData implements HttpSessionBindingListener {

private Connection conn;
private ResultSet rs;
private PreparedStatement ps;

/** セッション開始時の処理 **/
public void valueBound (HttpSessionBindingEvent event) {

HttpSession hs = event.getSession();
conn = (Connection) hs.getAttribute("conn");
rs = (ResultSet) hs.getAttribute("rs");
ps = (PreparedStatement) hs.getAttribute("ps");
}

/** セッション終了時の処理 **/
public void valueUnbound (HttpSessionBindingEvent event) {

System.out.println("valueUnBound1");
hs = event.getSession();

if (rs != null) {
try {
rs.close();
}
catch (SQLException sqle) {
System.err.println(sqle.getMessage());
}
rs = null;
}
if (ps != null) {
try {
ps.close();
}
catch (SQLException sqle) {
System.err.println(sqle.getMessage());
}
ps = null;
}
if (conn != null) {
try {
conn.close();
}
catch (SQLException sqle) {
System.err.println(sqle.getMessage());
}
conn = null;
}
}
}

 上記のように、はじめにグローバル変数としてConnection、ResultSet
 PreparedStatementを宣言しておき、セッションの開始処理時に
 セッションに登録されたコネクション等の情報をグローバル変数に格納して
 おきます。んでもって、セッションの終了時にグローバル変数にいれていた
 コネクション情報をクローズすることによってめでたくセッションに登録した
 コネクションを接続プールに返却できるよーになりました(喜)
 
 話はかわりますが、まりりさんどーやらウィンドウクローズ時にイベントを
 捕らえられないみたいですね・・・。まちがったこと言って申し訳ない
 m(_ _)mペコリンコ。ちょっとコーディングやってみましたが速攻
 頭かかえてしまいました・・(汗)みなさまのおっしゃるとおりJavaScript
 に依存してしまうコーディングはなるべくさけるようにしたいと思います。

 あと、みなさまの意見で大半をしめたのが一回一回select文を投げると
 いうことでしが、その場合、ページングの途中でデータが挿入された際に
 ページングの整合性がおかしくなってしまうと思いますが、その場合の解決法
 はあるのでしょうか?私も、この方法でやろーとしましたが、上司に
 「整合性がとれてないので ダメ」といわれてしまいました・・トホホ
 なにか情報がありましたらご教示ください。



[ メッセージ編集済み 編集者: 忍者鳥取県 編集日時 2003-09-09 16:34 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-09-01 20:35
引用:

忍者鳥取県さんの書き込み (2003-09-01 17:20) より:
 うほほほほ
 いままで色々協力してくれた皆様方まことにありがとう
 ございました。 m(_ _)mペコリ
 な・・なんと!!! 
 スレッドの題目に書いていた内容が!! 
 解決しました!!! (・_・、)(感涙)

 上記のように、はじめにグローバル変数としてConnection、ResultSet
 PreparedStatementを宣言しておき、セッションの開始処理時に
 セッションに登録されたコネクション等の情報をグローバル変数に格納して
 おきます。んでもって、セッションの終了時にグローバル変数にいれていた
 コネクション情報をクローズすることによってめでたくセッションに登録した
 コネクションを接続プールに返却できるよーになりました(喜)

 あと、みなさまの意見で大半をしめたのが一回一回select文を投げると
 いうことでしが、その場合、ページングの途中でデータが挿入された際に
 ページングの整合性がおかしくなってしまうと思いますが、その場合の解決法
 はあるのでしょうか?私も、この方法でやろーとしましたが、上司に
 「整合性がとれてないので ダメ」といわれてしまいました・・トホホ
 なにか情報がありましたらご教授ください。


解決の糸口が見えたとのことで、よかったと思います・・・。
ページングは、同時ユーザーからの上書き、追加、削除があった場合、ズレることがあります。
そのため、いろいろと苦労しています。
ちなみに以前発言したオフライン処理についてですが、これは上書きされないことが保証され
ている場合ぐらいしか使えないですね(汗)。
ところで、忍者鳥取県様のソースは本当にその問題は解決できているのでしょうか?
もう1点質問がありまして、グローバル変数をここに使って問題ありませんか?
(同時アクセス者がいた場合、変数の値が書き換わってしまうことがないかどうかが心配。
その可能性がなければOKですが)。

スキルアップ/キャリアアップ(JOB@IT)