- PR -

リクエストフォワードについて質問

投稿者投稿内容
Face
常連さん
会議室デビュー日: 2003/06/22
投稿数: 43
投稿日時: 2005-04-23 16:19
現在、サーブレットのリクエストフォワードに関して
どうしても解決できない現象があります。
もし、何かご存知の方がいらっしゃったら御指導願えないでしょうか。
よろしくお願いいたします。

【現象】-------------------------------------------------------------
1、Sample extends HttpServlet implements SingleThreadModel
  と宣言したクラスがある。

2、このクラスにおいてdoPost()メソッドをオーバーライドし、
  シングルスレッドになるように処理を記述

3、doPost()内で、下記条件のサーブレット、Sample2に「フォワード」する
  ((条件))
  ・Sample2 extends HttpServlet implements SingleThreadModelと宣言
  ・このクラス内で、シングルスレッドで無いクラスSample3のインスタンス
   を生成する
  ・Sample3は「synchronized」で宣言されたメソッドを持ち、
   これがSample2において実行される

4、Sample3の「synchronized」で宣言されたメソッド実行において
  そのメソッド中でデータベースに処理時間の長いSQLの応答
  待ちを発生させる

5、この状態で(待ちが発生したまま)新たに
  Sampleクラスにリクエストを要求するとレスポンスが
  返却されない。(何回も複数リクエストを要求しても応答無し)
  (※「フォワード」でSample2に処理が移っていない事を確認)

6、Sample3の「synchronized」で宣言されたメソッド実行において
  待ち状態が解除(処理が終了)すると5において行った
  リクエスト要求(複数)が一斉に処理され始めて応答が返ってくる。
---------------------------------------------------------------------

「synchronized」で宣言されたメソッドで待ちが発生しているときに
オブジェクトがロックされ、排他制御がかかっている事が原因
と考えていたのですが、「フォワード」自体が上手くいっていない
ので他の原因ではないかと調査中しています。

何かこのような条件の下でフォワード処理が待ち状態に
なることは考えられるでしょうか?

現象の説明が言葉ではなかなか上手く表せず、質問の意図が
判りにくいため回答しづらい面もあるかと思いますが、
よろしくお願いいたします。
Face
常連さん
会議室デビュー日: 2003/06/22
投稿数: 43
投稿日時: 2005-04-23 16:22
フォワード処理についての条件を書き込んでいませんでした。
フォワードは下記のように行っております。

getServletContext().getNamedDispatcher( servletname ).forward( request, response ) ;
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-04-23 22:10
SampleはSingleThreadModelですからね。
forwardから発生した一連の処理が全部終わらない限りSampleへの次のリクエストは解決されないと思いますよ。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2005-04-24 02:48
引用:
forwardから発生した一連の処理が全部終わらない限りSampleへの次のリクエストは解決されないと思いますよ。


私もそう思いますが、使用するコンテナによっては常にそうとは限らないです。
APIドキュメントのSingleThreadModelを引用すると、
引用:
サーブレットコンテナは、サーブレットの 1 つのインスタンスへのアクセスに対し排他制御を行うことによって、またはサーブレットインスタンスのプールを保持し、各新規要求を未使用のサーブレットへ振り分けることによって、この保証を行います。


とありますから、インスタンスプールを使用するものでは平行処理可能になります。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-04-24 14:08
問題解決というより蛇足ですが、
SingleThreadModelは最新バージョンでは推奨されていません。
今後の互換性の為に使用しないことをお勧めします。

Face
常連さん
会議室デビュー日: 2003/06/22
投稿数: 43
投稿日時: 2005-04-25 19:45
たくさんのアドバイス有難うございます。
Anthyhimeさんにご指摘いただいたように、
シングルスレッドのため、待ち行列が発生して
処理の待ち時間が発生しているのかと疑っておりました。

しかし、Kissingerさんが書いてくださったように、
インスタンスを個別に作成することで、
それぞれのスレッドが干渉しないようにし、
シングルスレッドを実現しているという事を知りました。
ほとんどのサーブレットコンテナは待ち行列ではなく、
新たにインスタンスプールよりひっぱってくるように
作成されているとの事でした。

この場合、
「forwardから発生した一連の処理」
では他と違った扱われ方をしているのかと考え
質問させていただきました。

Anthyhimeのご指摘の内容に関して
もう少し詳しくお聞かせ願えると幸いです。
よろしくお願いいたします。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-04-25 23:02
サーブレットのインスタンスプールは明示的にサーブレットコンテナに指定しないと普通は有効にならないです。
ですので待ち行列が発生すると言う解釈でまずあっています。
Face
常連さん
会議室デビュー日: 2003/06/22
投稿数: 43
投稿日時: 2005-04-26 12:25
Anthyhimeさん、有難うございます。
ご指摘の通り、待ち行列が発生していたようなので、
SampleのSingleThreadModelを実装しないようにすると
ロックされませんでした。

しかし、どうしてもシングルスレッドで実行したい
処理なのですが、このような場合、何らかの設定や
プログラミングで、インスタンスプールを明示的に
利用するように出来ないでしょうか。
サーブレットの動作環境の設定ファイルや
web.xmlのDTDなどを調べてみましたがそれらしき
方法等は発見できませんでした。

ご存知の方がいらっしゃったら、
御指導願います。

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