(57)【特許請求の範囲】
【請求項１】
ステートレスな環境において複数リクエストトランザクションを処理するためにコンピュータシステムで実行される方法であって、前記コンピュータシステムは、１つ以上のコンピュータプロセッサを含み、ブラウザを実行するクライアントが前記コンピュータシステムに接続されており、前記１つ以上のコンピュータプロセッサは、命令を実行することにより、カートリッジ実行エンジンと、カートリッジと、トランザクションマネージャとして機能し、前記複数リクエストトランザクションは、前記ブラウザから送られるメッセージ中で特定されたオペレーションを構成し、前記方法は、
前記カートリッジ実行エンジンが、前記カートリッジに向けられて１つ以上のブラウザから送られたメッセージを代行受信するステップと、
前記カートリッジ実行エンジンが、前記メッセージが前記トランザクションと関連づけられているか否かを判定するステップとを含み、
前記メッセージが前記トランザクションと関連づけられている場合に実行されるステップとして、
前記カートリッジ実行エンジンが前記メッセージに基づくトランザクション制御メッセージを、前記カートリッジとは別に実現されるトランザクションマネージャに送るステップと、
前記カートリッジ実行エンジンが前記メッセージに基づくオペレーションメッセージを前記カートリッジに送るステップと、
前記カートリッジ実行エンジンからの前記オペレーションメッセージに応答して、前記カートリッジが、前記オペレーションが属する複数リクエストトランザクションについてのトランザクションの状態を示す情報を持続的に記憶することなく、前記オペレーションメッセージ中で特定されたオペレーションを実行するステップと、
前記トランザクションマネージャが、前記トランザクションの状態を示す情報を前記カートリッジ実行エンジンから取得するステップと、
前記トランザクションマネージャが、取得した前記トランザクションの状態を示す情報からトランザクションＩＤ（Identification）を作成するステップであって、前記トランザクションＩＤは、前記クライアントに送信されるものであり、かつ、前記クライアントによって記憶されるものである、前記作成するステップと、
前記カートリッジ実行エンジンが、前記複数リクエストトランザクションのうちの他のリクエストと、前記記憶している前記トランザクションＩＤとを、前記クライアントから受信するステップと、
前記カートリッジ実行エンジンからの前記トランザクション制御メッセージに応答して、前記トランザクションマネージャが、前記複数リクエストトランザクションのオペレーションの全てを、アトミック単位としてコミットまたはロールバックさせるステップとを含む、方法。
【請求項２】
前記オペレーションメッセージ中で特定された前記オペレーションをコミットさせるステップが、前記トランザクションマネージャが１以上のデータベースサーバにコミットメッセージを送るステップを含み、このコミットメッセージは、前記１以上のデータベースサーバに、前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてコミットさせる、請求項１に記載の方法。
【請求項３】
前記オペレーションメッセージ中で特定されたオペレーションをロールバックさせるステップが、前記トランザクションマネージャが１以上のデータベースサーバにロールバックメッセージを送るステップを含み、このロールバックメッセージは、前記１以上のデータベースサーバに前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてロールバックさせる、請求項１に記載の方法。
【請求項４】
トランザクションに関連づけられているメッセージは、トランザクションＩＤに関連づけられ、トランザクションＩＤが特定のメッセージに関連づけられているブラウザを識別する、請求項１に記載の方法。
【請求項５】
トランザクションＩＤがクッキーとして維持され、クッキーが特定のメッセージに関連づけられているブラウザに維持される、請求項４に記載の方法。
【請求項６】
トランザクションＩＤが、特定のメッセージに関連づけられているブラウザに表示される１以上のウェブページにおける１以上のタグに関連づけられているＵＲＬとして維持される、請求項４に記載の方法。
【請求項７】
前記カートリッジ実行エンジンが、前記メッセージがトランザクションと関連づけられているか否かを判定するステップは、
特定のメッセージに関連づけられているＵＲＬを獲得するステップと、
前記特定のメッセージに関連づけられているＵＲＬを用いて、前記特定のメッセージに関連づけられているトランザクションの状態を判定するステップとを含む、請求項１に記載の方法。
【請求項８】
トランザクションＩＤがタイムアウト期間と関連づけられ、タイムアウト期間の満了が、トランザクションＩＤと関連づけられているトランザクションは無効とされるべきであることを示す、請求項４に記載の方法。
【請求項９】
ステートレスな環境においてコンピュータシステムが複数リクエストトランザクションを処理するための命令シーケンスを保持するコンピュータ読み取り可能な記録媒体であって、前記コンピュータシステムは、１つ以上のコンピュータプロセッサを含み、前記コンピュータシステムには、ブラウザを実行するクライアントが接続されており、前記複数リクエストトランザクションは前記ブラウザから送られるメッセージ中で特定されたオペレーションを構成し、前記命令シーケンスは命令を含み、前記命令は１つ以上のプロセッサによって実行され、前記命令は、前記１つ以上のコンピュータプロセッサに、
カートリッジ実行エンジンとして、カートリッジに向けられた１つ以上のブラウザから送られたメッセージを代行受信するステップと、
前記カートリッジ実行エンジンとして、前記メッセージがトランザクションと関連づけられているか否かを判定するステップとを実行させ、
前記メッセージがトランザクションと関連づけられていれば、
前記カートリッジ実行エンジンとして、前記メッセージに基づくトランザクション制御メッセージを、前記カートリッジとは別に実現されるトランザクションマネージャに送るステップと、
前記カートリッジ実行エンジンとして、前記メッセージに基づくオペレーションメッセージを前記カートリッジに送るステップと、
前記カートリッジ実行エンジンからの前記オペレーションメッセージに応答して、前記カートリッジとして、オペレーションが属する複数リクエストトランザクションについてのトランザクションの状態を示す情報を持続的に記憶することなく、前記オペレーションメッセージ中で特定されたオペレーションを実行するステップと、
前記トランザクションマネージャとして、前記トランザクションの状態を示す情報を前記カートリッジ実行エンジンから取得するステップと、
前記トランザクションマネージャとして、取得した前記トランザクションの状態を示す情報からトランザクションＩＤ（Identification）を作成するステップであって、前記トランザクションＩＤは、前記クライアントに送信されるものであり、かつ、前記クライアントによって記憶されるものである、前記作成するステップと、
前記カートリッジ実行エンジンとして、前記複数リクエストトランザクションのうちの他のリクエストと、前記記憶している前記トランザクションＩＤとを、前記クライアントから受信するステップと、
前記カートリッジ実行エンジンからの前記トランザクション制御メッセージに応答して、前記トランザクションマネージャとして、複数リクエストトランザクションのオペレーションの全てを、アトミック単位としてコミットまたはロールバックさせるステップとを実行させる、コンピュータ読み取り可能な記録媒体。
【請求項１０】
トランザクションに関連づけられているメッセージがトランザクションＩＤと関連づけられ、トランザクションＩＤが特定のメッセージに関連づけられているブラウザを識別する、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項１１】
前記カートリッジ実行エンジンが前記メッセージがトランザクションと関連づけられているか否かを判定するステップが、
特定のメッセージに関連づけられているＵＲＬを獲得するステップと、
特定のメッセージに関連づけられているＵＲＬを用いて特定のメッセージに関連づけられているトランザクションの状態を判定するステップとを含む、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項１２】
ステートレスな環境において複数リクエストトランザクションを処理するためのシステムであって、前記システムは、ブラウザを実行するクライアントに接続されており、複数リクエストトランザクションは、前記ブラウザから送られるメッセージ中で特定されたオペレーションを構成し、前記システムは、
メモリと、
メモリに結合された１以上のプロセッサと、
メモリ内に含まれる１組のコンピュータ命令とを含み、１組のコンピュータ命令は、１以上のプロセッサによって実行されるとき１以上のプロセッサに以下のステップを実行させるコンピュータ命令を含み、前記ステップは、
カートリッジ実行エンジンとして、カートリッジに向けられて１つ以上のブラウザから送られたメッセージを代行受信するステップと、
前記カートリッジ実行エンジンとして、前記メッセージがトランザクションと関連づけられているか否かを判定するステップとを含み、
前記メッセージがトランザクションに関連づけられている場合に実行されるステップとして、
前記カートリッジ実行エンジンとして、前記メッセージに基づくトランザクション制御メッセージを前記カートリッジとは別に実現されるトランザクションマネージャに送るステップと、
前記カートリッジ実行エンジンとして、前記メッセージに基づくオペレーションメッセージを前記カートリッジに送るステップと、
前記カートリッジ実行エンジンからの前記オペレーションメッセージに応答して、前記カートリッジとして、オペレーションが属する複数リクエストトランザクションについてのトランザクションの状態を示す情報を持続的に記憶することなく、前記オペレーションメッセージ中で特定されたオペレーションを実行するステップと、
前記トランザクションマネージャとして、前記トランザクションの状態を示す情報を前記カートリッジ実行エンジンから取得するステップと、
前記トランザクションマネージャとして、取得した前記トランザクションの状態を示す情報からトランザクションＩＤ（Identification）を作成するステップであって、前記トランザクションＩＤは、前記クライアントに送信されるものであり、かつ、前記クライアントによって記憶されるものである、前記作成するステップと、
前記カートリッジ実行エンジンとして、前記複数リクエストトランザクションのうちの他のリクエストと、前記記憶している前記トランザクションＩＤとを、前記クライアントから受信するステップと、
前記カートリッジ実行エンジンからの前記トランザクション制御メッセージに応答して、前記トランザクションマネージャが複数リクエストトランザクションのオペレーションを、アトミック単位としてコミットまたはロールバックさせるステップとを含む、システム。
【請求項１３】
トランザクションに関連づけられているメッセージがトランザクションＩＤに関連づけられ、トランザクションＩＤが特定のメッセージに関連づけられているブラウザを識別する、請求項１２に記載のシステム。
【請求項１４】
前記カートリッジ実行エンジンが前記メッセージがトランザクションと関連づけられているか否かを判定するステップは、
特定のメッセージに関連づけられているＵＲＬを獲得するステップと、
特定のメッセージに関連づけられているＵＲＬを用いて、特定のメッセージに関連づけられているトランザクションの状態を判定するステップとを含む、請求項１２に記載のシステム。
【請求項１５】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンがトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションを開始させる、請求項１に記載の方法。
【請求項１６】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンが前記トランザクションマネージャにトランザクション制御メッセージを送り、前記トランザクションマネージャに前記トランザクションをコミットさせる、請求項１に記載の方法。
【請求項１７】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンは前記トランザクションマネージャにトランザクション制御メッセージを送り、前記トランザクションマネージャに前記トランザクションをロールバックさせる、請求項１に記載の方法。
【請求項１８】
ブラウザに表示されたウェブページのタグに関連づけられる制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記開始トランザクションコマンドを受信するステップをさらに含む、請求項１５に記載の方法。
【請求項１９】
ブラウザに表示されるウェブページのタグに関連づけられる制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記コミットトランザクションコマンドを受信するステップをさらに含む、請求項１６に記載の方法。
【請求項２０】
ブラウザに表示されるウェブページのタグに関連づけられる制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記ロールバックトランザクションコマンドを受信するステップをさらに含む、請求項１７に記載の方法。
【請求項２１】
前記オペレーションメッセージ中で特定されたオペレーションをコミットさせるステップが、前記トランザクションマネージャがコミットメッセージを１以上のデータベースサーバに送るステップを含み、コミットメッセージが前記１以上のデータベースサーバに、前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてコミットさせる、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項２２】
前記オペレーションメッセージ中で特定されたオペレーションをロールバックさせるステップが、前記トランザクションマネージャがロールバックメッセージを１以上のデータベースサーバに送るステップを含み、ロールバックメッセージは、前記１以上のデータベースサーバに、前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてロールバックさせる、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項２３】
前記カートリッジ実行エンジンとして、メッセージを代行受信するステップが、前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記コンピュータ読み取り可能な記録媒体は、前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンがトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションを開始させるステップを実行するための命令をさらに含む、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項２４】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記コンピュータ読み取り可能な記録媒体は、前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンがトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションをコミットさせるステップを実行するための命令をさらに含む、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項２５】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記コンピュータ読み取り可能な記録媒体は、前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンがトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションをロールバックさせるステップを実行するための命令をさらに含む、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項２６】
トランザクションＩＤをクッキーとして維持するための命令をさらに含み、クッキーは、特定のメッセージに関連づけられているブラウザに維持される、請求項１０に記載のコンピュータ読み取り可能な記録媒体。
【請求項２７】
トランザクションＩＤをＵＲＬとして維持するための命令をさらに含み、ＵＲＬは、特定のメッセージに関連づけられているブラウザに表示される１以上のウェブページにおける１以上のタグに関連づけられる、請求項１０に記載のコンピュータ読み取り可能な記録媒体。
【請求項２８】
タイムアウト期間をトランザクションＩＤと関連づけるための命令をさらに含み、タイムアウト期間の満了が、トランザクションＩＤと関連づけられているトランザクションは無効とされるべきであることを示す、請求項１０に記載のコンピュータ読み取り可能な記録媒体。
【請求項２９】
ブラウザに表示されたウェブページのタグに関連づけられている制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記開始トランザクションコマンドを受信するステップを実行するための命令をさらに含む、請求項２３に記載のコンピュータ読み取り可能な記録媒体。
【請求項３０】
ブラウザに表示されたウェブページのタグに関連づけられている制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記コミットトランザクションコマンドを受信するステップを実行するための命令をさらに含む、請求項２４に記載のコンピュータ読み取り可能な記録媒体。
【請求項３１】
ブラウザに表示されたウェブページのタグに関連づけられている制御の選択に応答して、前記カートリッジ実行エンジンにおいてＵＲＬの形式で前記ロールバックトランザクションコマンドを受信するステップを実行するための命令をさらに含む、請求項２５に記載のコンピュータ読み取り可能な記録媒体。
【請求項３２】
前記オペレーションメッセージ中で特定されたオペレーションをコミットさせるステップが、前記トランザクションマネージャがコミットメッセージを１以上のデータベースサーバに送るステップを含み、このコミットメッセージが、前記１以上のデータベースサーバに、前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてコミットさせる、請求項１２に記載のシステム。
【請求項３３】
前記オペレーションメッセージ中で特定されたオペレーションをロールバックさせるステップが、前記トランザクションマネージャがロールバックメッセージを１以上のデータベースサーバに送るステップを含み、ロールバックメッセージが前記１以上のデータベースサーバに、前記複数リクエストトランザクションに関連づけられている変更をアトミック単位としてロールバックさせる、請求項１２に記載のシステム。
【請求項３４】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンが開始トランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンはトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションを開始させる、請求項１２に記載のシステム。
【請求項３５】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンがコミットトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンはトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションをコミットさせる、請求項１２に記載のシステム。
【請求項３６】
前記カートリッジ実行エンジンがメッセージを代行受信するステップが、前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを代行受信するステップを含み、
前記カートリッジ実行エンジンがロールバックトランザクションコマンドを含むメッセージを受信したことに応答して、前記カートリッジ実行エンジンはトランザクション制御メッセージを前記トランザクションマネージャに送り、前記トランザクションマネージャに前記トランザクションをロールバックさせる、請求項１２に記載のシステム。
【請求項３７】
前記カートリッジに向けられたメッセージを代行受信する前に、開始トランザクションＵＲＩ（Uniform Resource Indicator）を「開始」属性に関係付けるメタデータを蔵置するステップと、
前記カートリッジに向けられたメッセージを代行受信することに応答して、前記代行受信されたメッセージのうちの特定のメッセージが前記開始トランザクションＵＲＩを含むか否かを判定するステップと、
前記特定のメッセージが前記開始トランザクションＵＲＩを含むとの判定に応答して、トランザクション制御メッセージ内に、前記トランザクションマネージャにトランザクションを開始させる開始トランザクション識別子を含めるステップとをさらに含む、請求項１に記載の方法。
【請求項３８】
前記カートリッジに向けられたメッセージを代行受信する前に、開始トランザクションＵＲＩ（Uniform Resource Indicator）を「開始」属性に関係付けるメタデータを蔵置するステップと、
前記カートリッジに向けられたメッセージを代行受信することに応答して、前記代行受信されたメッセージのうちの特定のメッセージが前記開始トランザクションＵＲＩを含むか否かを判定するステップと、
前記特定のメッセージが前記開始トランザクションＵＲＩを含むとの判定に応答して、トランザクション制御メッセージ内に、前記トランザクションマネージャにトランザクションを開始させる開始トランザクション識別子を含めるステップとを実行するための命令をさらに含む、請求項９に記載のコンピュータ読み取り可能な記録媒体。
【請求項３９】
前記カートリッジに向けられたメッセージを代行受信する前に、開始トランザクションＵＲＩ（Uniform Resource Indicator）を「開始」属性に関係付けるメタデータを蔵置するステップと、
前記カートリッジに向けられたメッセージを代行受信することに応答して、前記代行受信されたメッセージのうちの特定のメッセージが前記開始トランザクションＵＲＩを含むか否かを判定するステップと、
前記特定のメッセージが前記開始トランザクションＵＲＩを含むとの判定に応答して、トランザクション制御メッセージ内に、前記トランザクションマネージャにトランザクションを開始させる開始トランザクション識別子を含めるステップとを、前記コンピュータ命令が１以上のプロセッサによって実行されるときに、１以上のプロセッサによって実行されるステップとして、さらに含む、請求項１２に記載のシステム。
【請求項４０】
前記カートリッジ実行エンジンが前記メッセージに基づくトランザクション制御メッセージを、前記カートリッジとは別に実現されるトランザクションマネージャに送る前記ステップは、前記カートリッジ実行エンジンが、前記メッセージに含まれるトランザクションの状態を示す前記情報に基づくトランザクション制御メッセージを、前記カートリッジとは別に実現されるトランザクションマネージャに送るステップを含み、
前記カートリッジ実行エンジンが前記メッセージに基づくオペレーションメッセージを前記カートリッジに送る前記ステップは、前記カートリッジ実行エンジンが、前記メッセージに含まれるトランザクションの状態を示す前記情報に基づくオペレーションメッセージを、前記カートリッジに送るステップを含む、請求項１に記載の方法。
【請求項４１】
前記メッセージを生成した１つ以上のブラウザに、トランザクションの状態を示す前記情報を送信させるステップをさらに含む、請求項１に記載の方法。
【請求項４２】
前記メッセージを生成した１つ以上のブラウザに、トランザクションの状態を示す前記情報を送信させる前記ステップは、前記メッセージを生成した１つ以上のブラウザに、１つ以上のクッキーでトランザクションの状態を示す前記情報を送信させるステップを含む、請求項４１に記載の方法。
【請求項４３】
前記メッセージを生成した１つ以上のブラウザに、トランザクションの状態を示す前記情報を送信させる前記ステップは、前記メッセージを生成した１つ以上のブラウザに、１つ以上のＵＲＬでトランザクションの状態を示す前記情報を送信させるステップを含む、請求項４１に記載の方法。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、ネットワーク接続されたコンピュータシステムにおけるトランザクションの処理に関し、より具体的には、ステートレスなウェブ環境における複数リクエストのトランザクションの処理に関する。
【０００２】
【発明の背景】
ワールド・ワイド・ウェブ（World Wide Web）はインターネット（Internet）上のサーバのネットワークを含み、その各々は１つ以上のＨＴＭＬ（Hypertext Markup Language：ハイパテキスト・マークアップ言語）ページに関連付けられている。サーバに関連付けられているＨＴＭＬページは、情報と、そのサーバおよび（通常は）他のサーバ上の他の文書へのハイパテキストリンクとを提供する。サーバはハイパテキスト・トランスファー・プロトコル（ＨＴＴＰ：Hypertext Transfer Protocol）を用いてクライアントと通信する。サーバはクライアントからのＨＴＭＬページに関するリクエストを聞くことから、多くの場合、「リスナ」と称される。
【０００３】
ワールド・ワイド・ウェブのユーザはブラウザと呼ばれるクライアントプログラムを用いてリスナから情報をリクエストし、デコードし、表示する。ブラウザのユーザがあるＨＴＭＬページ上のリンクを選択すると、そのページを表示しているブラウザはそのリンク内で特定されるユニバーサル・リソース・ロケータ（ＵＲＬ：Universal Resource Locator）と関連付けられるリスナにインターネットを通じてリクエストを送る。そのリクエストに応答して、リスナはそのリクエストを発行したブラウザにリクエストされた情報を送信する。ブラウザは情報を受取り、受取った情報をユーザに示し、次のユーザリクエストを待つ。
【０００４】
従来、リスナに蔵置される情報は静的ＨＴＭＬページの形態である。静的ＨＴＭＬページは、ウェブブラウザからのリクエストに先立ち作成されリスナに蔵置される。リクエストに応答して、静的ＨＴＭＬページが単に記憶から読出され、リクエストを行なっているブラウザに送信される。現在、ブラウザリクエストに応答して動的オペレーションを行なうリスナを開発しようとする趨勢にある。たとえば、リスナはリクエストに応答する際にデータベースにクエリーを発行し、そのクエリーの結果を含むウェブページを動的に構成し、動的に構成されたＨＴＭＬページをリクエストを行なっているブラウザに送信してもよい。動的オペレーションを行なうために、リスナの機能性を向上または増強させなければならない。動的オペレーションをサポートするようリスナを拡張するためにさまざまなアプローチが開発されてきた。
【０００５】
ウェブの主な特徴の１つは、これがステートレスな環境を提供するということである。すなわち、ＨＴＴＰは、メッセージ間の関係を示す機構を全く用いず、１メッセージ単位で情報を通信する。これは、現在のリクエストに対しサービスを行なうプロセスが、現在のリクエストが前のリクエストと同じクライアントから来たものか否かを判定できない、ということを意味する。さらに、このサービスプロセスは、現在のリクエストが前のリクエストといかに関係しているか、または関係しているか否かを判定することができない。
【０００６】
ステートレスな環境を用いることに関する欠点は、複数リクエストのトランザクションを処理するのが困難であるという点である。複数リクエストトランザクションは、（１）２以上のリクエストにおいて特定される、および（２）作業のアトミック単位として実行しなければならない、１組のオペレーションである。たとえば、複数リクエストのトランザクションは、購入物品Ａ、売却物品Ｂ、および手持ちの物品数を反映するための在庫の更新などの３つの別々のオペレーションを含むことがある。これら３つのオペレーションの各々は別々のリクエストにおいて特定できるが、各オペレーションは、３つのオペレーションすべてが実行され得る場合のみ実行されるべきである。購入物品Ａ、売却物品Ｂおよび在庫の更新が同じ単一のトランザクションからのものであることを適切に決定するためには、３つのリクエストを受取るサービスプロセスによってトランザクションのステート情報を保持しておく必要がある。
【０００７】
このステートレスの問題に対して考えられ得る解決策の１つは、リクエスト発行ソースの各々（各「クライアント」）についてサービスプロセスを発生することである。クライアントからのリクエストを受取るたびに、そのリクエストを処理するために同じサービスプロセスが呼出される。所与のクライアントに対して同じプロセスが起動されるので、特定のトランザクションに対するトランザクションステート情報はそれに関連づけられるサービスプロセスによって維持でき、よって複数リクエストトランザクションの処理が可能になる。
【０００８】
しかしながら、この解決策は重大な欠点を有する。第１に、ほとんどのクライアントはサービスプロセスに対して継続的にリクエストを与えるわけではないので、各クライアントに対して別々のサービスプロセスを維持するのは無駄である。各クライアントリクエストの間では、サービスプロセスは単に待機し、何の作業も実行せずにシステムリソースを消費する。この解決策の第２の欠点は、これがスケーラブルでないということである。サービスプロセスが各クライアントに対して発生し、かつ維持されると、システムリソースは、たとえクライアント数が比較的少なくても、すぐに消費されるであろう。したがって、各クライアントに対してサービスプロセスを発生させることは、大規模システムに対しては実行不可能な解決策である。
【０００９】
第２に考えられ得る解決策は、各サービスプロセスに対し、それが現在処理しているトランザクションの現在のステートを維持するよう要請することである。トランザクションのステート情報を維持することにより、各サービスプロセスは、複数リクエストが確実に正しく処理されるようにすることができる。
たとえば、背景についてのさらなる詳細、および本発明の実施例によって解決される問題は、１９９７年１０月３０日に出願され「データアクセスのためのシステムおよび方法（SYSTEM AND METHOD FOR DATA ACCESS）」と題された、特許協力条約（ＰＣＴ）に基づいて公開された国際出願（ＷＯ９７／４０４５７）に記載されている。この文書には、ステートレスプロトコルを用いてサーバのデータにアクセスする、クライアント−サーバシステムが記載される。サーバシステムをクライアントシステムとリンクさせることにより、ネットワーク上でのネットワーク通信の効率が向上する。記載によれば、初期クライアントシステムのトランザクションリクエストの各々に対して、サーバは一意の識別子またはトークンを生成し、これはネットワークを通じてクライアントシステムに戻され、このトークンを受け取ると、クライアントシステムがその接続を終了してそれを解放するまで、アクティブまたはオープンな状態でサーバに対する論理接続を保持するように作動する。サーバで、トークンは、サーバに保持されて後続のクライアントとの通信に用いられるクライアントステート情報（ユーザコンテキスト情報とも呼ばれる）を識別するために用いられる。クライアントからの後続の通信は、蔵置されているクライアントステート情報を識別するためにサーバが用いる、トークンを含む。したがって、サーバシステムとクライアントシステムとの間のネットワーク接続を生かしておくことにより、記載されたシステムはネットワークオーバヘッドを減じ、よってシステムオーバヘッド全体を減じることができる。
しかしながら、各サービスプロセスにトランザクションステート情報を維持するよう要請することに関する欠点は、このことにより、リクエストされたトランザクションステート情報を維持するために余分なコードを書くという負担が、各サービスプロセスの開発者にかかってしまうという点である。
【００１０】
以上の点を踏まえて、トランザクションステート情報を維持するためにサービスプロセスを必要としない、ステートレスな環境における複数リクエストトランザクションの処理のための機構を提供することが望ましい。
【００１１】
【発明の概要】
ステートレスな環境において複数リクエストトランザクションを処理するための方法およびシステムが提供される。
【００１２】
本発明の一局面によると、カートリッジ実行エンジンは、カートリッジに向けられたブラウザリクエストを代行受信する。カートリッジ実行エンジンは、このブラウザリクエストがトランザクションと関連づけられているか否かを判定する。ブラウザリクエストがトランザクションと関連づけられている場合、カートリッジ実行エンジンはトランザクションマネージャにトランザクション制御メッセージを送る。カートリッジ実行エンジンはまた、カートリッジにオペレーションメッセージも送る。カートリッジは、オペレーションメッセージ中で特定されたオペレーションを実行する。カートリッジ実行エンジンからのトランザクション制御メッセージに応答して、トランザクションマネージャは、複数リクエストトランザクションを作業のアトミック単位としてコミットさせるかまたはロールバックさせるかのいずれかを行なう。
【００１３】
本発明の別の局面によると、トランザクションに関連づけられたブラウザリクエストは、特定のブラウザリクエストに関連づけられたブラウザを識別するために用いられ得るトランザクションＩＤと関連づけられる。
【００１４】
本発明の別の局面によると、トランザクションに関連づけられたブラウザリクエストは、トランザクションＩＤと関連づけられ、特定のブラウザリクエストと関連づけられたブラウザを識別するために用いられる。
【００１５】
本発明の別の局面によると、トランザクションＩＤは特定のブラウザリクエストに関連づけられているブラウザ上のクッキーとして維持される。
【００１６】
本発明の別の局面によると、トランザクションＩＤは、特定のブラウザリクエストに関連づけられているブラウザ上のＵＲＬとして維持される。
【００１７】
この発明は限定によってではなく例によって、添付の図面において例示され、添付の図面において類似の参照番号は類似の要素を指す。
【００１８】
【好ましい実施例の詳細な説明】
ネットワークにわたって複数リクエストトランザクションを処理するための方法および装置を説明する。以下において説明のため、この発明の完全な理解をもたらすように数多くの特定の詳細事項を挙げている。しかしながら、当業者にはこの発明がこれらの特定の詳細事項がなくても実施できることが明らかになるであろう。場合によっては不必要にこの発明を曖昧にすることを避けるため周知の構造および装置をブロック図の形態で示している。
【００１９】
ハードウェアの概観
図１は、この発明の実施例が実装され得るコンピュータシステム１００を示すブロック図である。コンピュータシステム１００は、バス１０２または情報を通信するための他の通信機構と、バス１０２に結合され情報を処理するためのプロセッサ１０４とを含む。コンピュータシステム１００はまた、バス１０２に結合され情報およびプロセッサ１０４が実行すべき命令を蔵置するための、ランダムアクセスメモリ（ＲＡＭ）または他の動的記憶装置などのメインメモリ１０６を含む。メインメモリ１０６はまた、プロセッサ１０４が実行すべき命令の実行の間に一時変数または他の中間情報を蔵置するのに用いられてもよい。コンピュータシステム１００はさらに、バス１０２に結合され静的情報およびプロセッサ１０４に対する命令を蔵置するための読取専用メモリ（ＲＯＭ）１０８または他の静的記憶装置を含む。磁気ディスクまたは光ディスクなどの記憶装置１１０が設けられ、バス１０２に結合されて情報および命令を蔵置する。
【００２０】
コンピュータシステム１００はバス１０２を介して、陰極線管（ＣＲＴ）などの表示装置１１２に結合されコンピュータユーザに対して情報を表示してもよい。英数字および他のキーを含む入力装置１１４がバス１０２に結合され、情報およびコマンド選択をプロセッサ１０４に伝える。別のタイプのユーザ入力装置は、プロセッサ１０４に方向情報およびコマンド選択を伝え、かつ表示装置１１２上のカーソル移動を制御するためのマウス、トラックボールまたはカーソル方向キーなどのカーソル制御装置１１６である。この入力装置は典型的に２つの軸、すなわち第１の軸（たとえばｘ）および第２の軸（たとえばｙ）において２つの自由度を有し、これは装置が平面上の位置を特定できるようにする。
【００２１】
この発明はコンピュータシステム１００を用いてブラウザからのメッセージに応答して特定のオペレーションを行なうことに関する。この発明の一実施例によれば、プロセッサ１０４がメインメモリ１０６に含まれる１つ以上の命令の１つ以上のシーケンスを実行することに応答してコンピュータシステム１００がオペレーションを行なう。このような命令は、記憶装置１１０などの別のコンピュータ可読媒体からメインメモリ１０６に読込んでもよい。メインメモリ１０６に含まれる命令のシーケンスを実行することにより、プロセッサ１０４がここに説明するプロセスステップを実行することとなる。代替の実施例では、ソフトウェア命令の代わりにまたはソフトウェア命令と併せて、結線回路を用いてこの発明を実現してもよい。すなわち、この発明の実施例はハードウェア回路およびソフトウェアの如何なる特定の組合せにも限定されない。
【００２２】
「コンピュータ可読媒体」という用語はここでは、実行のためにプロセッサ１０４に命令を提供するのにかかわるすべての媒体を指して用いる。このような媒体は、不揮発性媒体、揮発性媒体および伝送媒体を含むが、これらに限定されない数多くの形態を取り得る。不揮発性媒体には、たとえば、記憶装置１１０などの光ディスクまたは磁気ディスクが含まれる。揮発性媒体には、メインメモリ１０６などのダイナミックメモリが含まれる。伝送媒体には、バス１０２を構成するワイヤを含む、同軸ケーブル、導線および光ファイバが含まれる。伝送媒体はまた、電波および赤外線データ通信において生成されるもののような音波または光波の形態を取ることもある。
【００２３】
コンピュータ可読媒体の一般的な形態にはたとえば、フロッピーディスク、フレキシブルディスク、ハードディスク、磁気テープまたは何らかの他の磁気媒体、ＣＤ−ＲＯＭおよび何らかの他の光媒体、パンチカード、せん孔テープおよび孔のパターンを有する何らかの他の物理的媒体、ＲＡＭ、ＰＲＯＭ、ＥＰＲＯＭ、ＦＬＡＳＨ−ＥＰＲＯＭおよび何らかの他のメモリチップまたはカートリッジ、以下に説明するような搬送波、またはコンピュータが読むことのできるものであればどのような他の媒体でも含まれる。
【００２４】
実行のために１つ以上の命令の１つ以上のシーケンスをプロセッサ１０４に与える上でさまざまな形態のコンピュータ可読媒体がかかわり得る。たとえば、命令は初めに遠隔コンピュータの磁気ディスク上に担持されてもよい。遠隔コンピュータは命令をそのダイナミックメモリにロードし、その命令をモデムを用いて電話回線を介して送ることができる。コンピュータシステム１００がローカルに有するモデムが電話回線上でデータを受取り、赤外線送信機を用いてそのデータを赤外線信号に変換できる。バス１０２に結合される赤外線検出器は赤外線信号で運ばれるデータを受取り、そのデータをバス１０２上に出力することができる。バス１０２はそのデータをメインメモリ１０６へ運び、そこからプロセッサ１０４は命令を取出して実行する。メインメモリ１０６が受取った命令は場合により、プロセッサ１０４による実行の前または後に記憶装置１１０に蔵置されてもよい。
【００２５】
コンピュータシステム１００はまた、バス１０２に結合される通信インターフェイス１１８を含む。通信インターフェイス１１８はローカルネットワーク１２２に接続されるネットワークリンク１２０への両方向データ通信結合を提供する。たとえば、通信インターフェイス１１８は、対応するタイプの電話回線に対してデータ通信接続を提供するサービス統合デジタル網（ＩＳＤＮ）カードまたはモデムであってもよい。別の例としては、通信インターフェイス１１８は、互換性のあるローカル・エリア・ネットワーク（ＬＡＮ）に対するデータ通信接続を提供するローカル・エリア・ネットワーク（ＬＡＮ）カードであってもよい。また、無線リンクを実現してもよい。このような実現例のいずれにおいても、通信インターフェイス１１８はさまざまなタイプの情報を表わすデジタルデータストリームを運ぶ電気信号、電磁気信号または光信号を送受信する。
【００２６】
ネットワークリンク１２０は典型的に１つ以上のネットワークを介して他のデータ装置へのデータ通信を提供する。たとえば、ネットワークリンク１２０はローカルネットワーク１２２を介してホストコンピュータ１２４または、インターネットサービスプロバイダ（ＩＳＰ：Internet Service Provider）１２６により運用されるデータ装置に対する接続を提供してもよい。ＩＳＰ１２６はこれを受けて、現在一般的に「インターネット」１２８と称される世界規模のパケットデータ通信網を介するデータ通信サービスを提供する。ローカルネットワーク１２２およびインターネット１２８はともに、デジタルデータストリームを運ぶ電気信号、電磁気信号または光信号を用いる。コンピュータシステム１００へまたはコンピュータシステム１００からデジタルデータを運ぶ、さまざまなネットワークを介する信号およびネットワークリンク１２０上の、通信インターネット１１８を介する信号は情報を運ぶ搬送波の典型的な形態である。
【００２７】
コンピュータシステム１００はネットワーク、ネットワークリンク１２０および通信インターネット１１８を介して、メッセージを送り、プログラムコードを含むデータを受取ることができる。インターネットの例では、サーバ１３０はインターネット１２８、ＩＳＰ１２６、ローカルネットワーク１２２および通信インターネット１１８を介してアプリケーションプログラムに対するリクエストされたコードを送信するかもしれない。
【００２８】
受取られたコードはそれが受取られると同時にプロセッサ１０４によって実行され、および／または後に実行するために記憶装置１１０または他の不揮発性記憶に蔵置されてもよい。このように、コンピュータシステム１００は搬送波の形態でアプリケーションコードを得ることもある。
【００２９】
アプリケーションサーバ機能の概要
図２は、この発明の一実施例に従って設計されたシステム２００のブロック図である。システム２００は、ＨＴＴＰプロトコルに従ってインターネット２０８にわたって複数のリスナ２１０、２１６および２２２と通信する複数のブラウザ２０２、２０４および２０６を含む。ブラウザからのリクエストに応答して、リスナはウェブアプリケーションサーバ２８０にここでカートリッジと称するソフトウェアモジュールを呼出させる。例示の実施例では、ウェブアプリケーションサーバ２８０は３つのカートリッジ２３０、２３４および２３８の実行を開始している。
【００３０】
ウェブアプリケーションサーバ２８０は、トランスポート・アダプタ２１２、２１８および２２４、ディスパッチャ２１４、２２０および２２６、認証サーバ２５２、仮想パスマネージャ２５０、リソースマネージャ２５４、コンフィギュレーションプロバイダ２５６および複数のカートリッジ実行エンジン２２８、２３２および２３６を含む、数多くの構成要素からなる。ウェブアプリケーションサーバ２８０のさまざまな構成要素について以下により詳しく説明する。
【００３１】
重要なことであるが、ウェブアプリケーションサーバ２８０の数多くの構成要素はオブジェクトリクエストブローカ（Object Request Broker）２８２などのマシン間通信機構を介して通信する。マシン間通信機構を用いることにより、ブラウザリクエストにおいて特定されるオペレーションを実行するカートリッジインスタンスは、リクエストを受取るリスナおよびリクエストを発行するブラウザとは異なるマシン上で実行することができる。カートリッジ・インスタンスがリスナとは異なるマシン上にあるため、リスナは障害のあるカートリッジ・インスタンスからよりよく隔離されることとなり、システムの信頼性および安全性が向上する。さらに、リスナが実行されるマシンと同じマシンでなく、数多くのマシン間でカートリッジインスタンスを実行する処理の負担を分散することによってシステムのスケーラビリティが大幅に増加する。複数のマシンにわたってカートリッジ・インスタンスの実行を分散できることから、いつどこで新しいカートリッジ・インスタンスを生じさせるかを決定するのに数多くのタイプの負荷の最適配分の技法を用いることができる。
【００３２】
システム２００内の典型的なオペレーションには一般的に以下の段階が含まれる。
【００３３】
ブラウザがインターネット２０８にわたってリクエストを送信する。
リスナがそのリクエストを受取ってトランスポートアダプタを介してディスパッチャに渡す。
【００３４】
ディスパッチャは仮想パスマネージャ２５０と通信してブラウザリクエストによって選択されたカートリッジを識別し、そのカートリッジが認証を必要とするか否かを判定する。
【００３５】
カートリッジが認証を必要とすれば、ディスパッチャは認証サーバ２５２と通信し、ブラウザが選択されたカートリッジにアクセスする権限を与えられているか否かを判定する。
【００３６】
認証サーバ２５２が、このブラウザは選択されたカートリッジにアクセスする権限を与えられていないと判定すれば、アクセスが拒絶されたことがブラウザに知らされる。
【００３７】
しかしながら、アクセスが権限を与えられているかまたは仮想パスマネージャ２５０が認証は必要ないと判定した場合、ディスパッチャは２つのうち１つのことを行なう。ディスパッチャがそのカートリッジに関する使用されていないインスタンスのことを知っている場合、ディスパッチャはそのインスタンスにリクエストを送る。そのカートリッジに関して使用されていないカートリッジインスタンスがない場合、ディスパッチャはリソースマネージャ２５４に新しいカートリッジインスタンスを作るよう依頼する。そのインスタンスがうまく起動した後に、カートリッジはその存在をリソースマネージャに知らせる。リソースマネージャ２５４はそこで、ディスパッチャに新しいインスタンスのことを知らせる。ディスパッチャはブラウザリクエストに基づいて変更されたリクエストを作り、その変更されたリクエストを新しいインスタンスに送る。
【００３８】
カートリッジインスタンスはその変更されたリクエストを処理して、ディスパッチャに応答を送る。
【００３９】
ディスパッチャはその応答をリスナを介してクライアントに戻す。
これらの段階について以下により詳しく説明する。
【００４０】
カートリッジ
カートリッジは特定のアプリケーションまたはシステム機能を行なうためのコードのモジュールである。カートリッジはシステム２００における分散の基本単位を形成する。この発明の一実施例によれば、カートリッジはユニバーサル・リソース・ロケータ（ＵＲＬ）を用いて名付けられる。すなわち、カートリッジ名（ＵＲＬ）には２つの部分、すなわちカートリッジが存在するサーバのＩＰアドレスと、コンパイルされたカートリッジコードのサーバディレクトリ構造における仮想パスとがある。カートリッジはＵＲＬを用いて名付けられるため、カートリッジ名空間はグローバルであり、文書などの他のウェブリソースにアクセスするのに用いられるのと同じメッセージ通信技術を用いてカートリッジにアクセスすることができる。
【００４１】
この発明の一実施例によれば、各カートリッジはすべてのカートリッジに対して共通の全体構造をもたらす標準インターフェイスを有する。この標準インターフェイスは、特定の条件の下でウェブアプリケーションサーバ２８０により呼出されるルーチンのインターフェイスを規定する。この発明の一実施例によれば、抽象カートリッジインターフェイスは以下のとおりである。
【００４２】
【表１】
0004729172.tif 000002
【００４３】
init()ルーチンはカートリッジインスタンスを初期化する役割を果たす。このことには、いくつかのサブオブジェクトのコンストラクタを呼出すことと、スレッドを予め分岐させることと、他のすべての必要となる共用リソースを獲得することとが含まれ得る。
【００４４】
shutdown()ルーチンはすべてのリソースを片付けカートリッジインスタンスをシャットダウンする役割を果たす。カートリッジインスタンスに対して一度shutdown()ルーチンが呼出されると、直ちにカートリッジインスタンスは後続のリクエストを処理するのに利用不可能となる。
【００４５】
authenticate()ルーチンではカートリッジのサービスをリクエストしているクライアントがそのサービスを用いることを許可されているかどうかを検証する。
【００４６】
exec()ルーチンはカートリッジに対してすべてのサービスリクエストをディスパッチする包括的なやり方である。
【００４７】
例示的カートリッジ
各カートリッジは、明確に定義された機能を行なうカートリッジとして構成されるか、またはあるアプリケーションのためのインタプリタまたはルーチン環境として作用するプログラム可能なカートリッジとして構成される。プログラム可能なカートリッジの一例はＰＬ／ＳＱＬランタイムであり、これは構造的問合せ言語（Structured Query Language）を用いるオラクルベースのプログラム言語（Oracle-based Programming Language）（ＰＬ／ＳＱＬ）に従ってデータベースクエリーを処理するよう構成される。ＰＬ／ＳＱＬランタイムはデータベースクエリーを有するブラウザリクエストを実行する。ＰＬ／ＳＱＬランタイムは、たとえば、データリンクを介してカートリッジインスタンスと通信しているデータベースサーバにアクセスすることによってリクエストを処理する。
【００４８】
プログラム可能なカートリッジの別の例はＪＡＶＡランタイムインタプリタである。ＪＡＶＡランタイムインタプリタカートリッジのおかげで、ウェブアプリケーション開発者らはブラウザリクエストを処理するためのサーバ側のＪＡＶＡアプリケーションを書くことができる。同様に、たとえば第三者のサーバによって実行されるプロセスにアクセスするなどの動的オペレーションをもたらすために、カスタムサーバをカートリッジとして構成してもよい。
【００４９】
ディスパッチャ
ディスパッチャは、リスナが受取ったリクエストを適当なカートリッジへ経路選択するよう構成されるソフトウェアモジュールである。この発明の一実施例によれば、ディスパッチャはサーバ側のプログラム拡張（すなわち、「プラグイン」）として実現される。そのため、ディスパッチャはそれらが属するリスナと同じアドレス空間にロードされそこで実行される。ディスパッチャはコンパイル時にリスナコードとリンクされてもよいし、実行時に動的にロードされてもよい。
【００５０】
例示される実施例では、ディスパッチャ２１４、２２０および２２６はそれぞれ、リスナ２１０、２１６および２２２に関連付けられる。ディスパッチャ２１４、２２０および２２６は、リスナ２１０、２１６および２２２が受取ったブラウザリクエストをカートリッジへ選択的に経路制御する。
【００５１】
たとえば、リスナ２１０がユニフォーム・リソース・ロケータ（ＵＲＬ：Uniform Resource Locator）の形態で運ばれるブラウザリクエストをインターネット２０８から受取ると仮定する。このブラウザリクエストは、たとえばＨＴＭＬページまたは実行すべきオペレーションであるウェブオブジェクトに対する識別子の役割を果たす。リスナ２１０はそのブラウザリクエストの解釈を全く試みることなくディスパッチャ２１４に受渡す。ブラウザリクエストを受取ると、ディスパッチャ２１４は、
（１）  仮想パスマネージャ２５０と通信してブラウザリクエストによって選択されるカートリッジを識別し、かつそのカートリッジが認証を要するかどうかを判定し、
（２）  そのカートリッジが認証を必要とする場合、認証サーバ２５２と通信してブラウザがその選択されたカートリッジにアクセスすることが許されるかどうかを判定し、
（３）  アクセスが許可された場合に、リソースマネージャと通信してブラウザリクエストを送るべき選択されたカートリッジの特定のインスタンスを定め、
（４）  カートリッジの特定されたインスタンスによる実行のため、変更されたブラウザリクエストを作りかつディスパッチする。
【００５２】
変更されたブラウザリクエストは元のブラウザリクエストで受取った情報を再パッケージする。変更されたブラウザリクエストはたとえば、カートリッジの正しいオペレーションに必要なデータを含むコンテキストオブジェクトを含んでいてもよい。カートリッジの正しいオペレーションに必要なデータには、たとえば、そのブラウザリクエストが関連付けられるトランザクションを識別するトランザクションＩＤが含まれる。
【００５３】
カートリッジがリクエストに返答すると、そのカートリッジはディスパッチャにその返答を送り、ディスパッチャはこの返答をリスナに渡してそのリクエストを開始したブラウザへ送信されるようにする。
【００５４】
コンフィギュレーションプロバイダ
この発明の一実施例によれば、ウェブアプリケーションサーバ２８０とともに用いるべきカートリッジはまずウェブアプリケーションサーバ２８０に登録される。登録プロセスの間、そのカートリッジに関する情報がコンフィギュレーションプロバイダ２５６に供給される。コンフィギュレーションプロバイダ２５６はその情報をメタデータ２５８として蔵置してウェブアプリケーションサーバ２８０の構成要素が後からアクセスできるようにする。
【００５５】
メタデータ２５８はたとえば、
（１）  カートリッジ名、
（２）  必要となるインスタンスの最小数、
（３）  インスタンスの最大数、
（４）  カートリッジを実装するコードの場所、
（５）  コールバック機能（初期化、リクエストハンドラ、シャットダウン）を実行するためカートリッジ実行エンジンが用いるプログラムに依存した関数名、
（６）  カートリッジを実行するためのマシンのリスト、
（７）  カートリッジのためのアイドルタイム（カートリッジのインスタンスがシャットダウンされる前にアイドル状態でいることができる時間量）、
（８）  オブジェクト識別子および
（９）  もしあれば、カートリッジとともに用いるべき、認証サービスのタイプを示すデータ
を含んでいてもよい。
【００５６】
オブジェクト識別子は、対応するカートリッジによるオペレーションの実行をリクエストするためにブラウザリクエストが供給しなければならないデータを特定する。オブジェクトタイプは特定のワードまたはＵＲＬであってもよく、または「/java」などの仮想パスを含んでいてもよい。
【００５７】
一度コンフィギュレーションプロバイダ２５６が特定のカートリッジに対するコンフィギュレーション情報をメタデータ２５８内に蔵置すると、そのカートリッジはウェブアプリケーションサーバ２８０が起動される際に自動的に登録される。
【００５８】
カートリッジがウェブアプリケーションサーバ２８０に登録された後、リソースマネージャ２５４はカートリッジに対する最小インスタンスをイニシエートする。一度最小数のインスタンスがイニシエートされると、ウェブアプリケーションサーバ２８０はブラウザリクエストを処理する準備が整う。
【００５９】
仮想パスマネージャ
上に述べたように、ディスパッチャは仮想パスマネージャ２５０と通信して各々の変更されたブラウザリクエストをどこに経路選択するかを定める。特定的には、各ブラウザリクエストは典型的にＵＲＬを含む。ブラウザリクエストを受取ると、ディスパッチャはそのリクエスト内のＵＲＬを仮想パスマネージャ２５０に送る。仮想パスマネージャ２５０はこれに応答して、もしあれば、ＵＲＬに関連付けられるカートリッジを識別するデータをディスパッチャに送る。
【００６０】
必要とされる情報をディスパッチャに供給するため、仮想パスマネージャ２５０はＵＲＬをカートリッジにマッピングするメタデータ２５８を調べる。ブラウザリクエストを受取ったことに応答して、仮想パスマネージャ２５０はマッピングデータを用いて、もしあれば、ブラウザリクエストに含まれるＵＲＬに対応するカートリッジを判定する。
【００６１】
たとえば、ブラウザリクエストが仮想パス「/java」で始まるＵＲＬリクエストである場合、マッピングにより、ＪＡＶＡインタプリタカートリッジが仮想パス「/java」を有するリクエストを取扱うよう構成されていることが示されるかもしれない。
【００６２】
この発明の一実施例によれば、仮想パスマネージャ２５０はまた、ＵＲＬに関連付けられたカートリッジが認証を必要とするかどうかを判定する。カートリッジが認証を要する場合、仮想パスマネージャ２５０はディスパッチャに送る応答において、認証が必要であることを示す。認証が必要でない場合、ディスパッチャは認証サーバ２５２を呼出すことなく、カートリッジのインスタンスに対する変更されたブラウザリクエストを作って送る。認証が必要である場合、変更されたリクエストをカートリッジのインスタンスに送出してもよいことを認証サーバが示した後に初めてディスパッチャはそのカートリッジのインスタンスに変更されたリクエストを送る。
【００６３】
リソースマネージャ
ウェブアプリケーションサーバ２８０のリソースマネージャ２５４は、カートリッジに対して予め定められた最小数のインスタンスをイニシエートし、各カートリッジのインスタンスの間で負荷の最適配分を行ない、所与のカートリッジの予め定められた最大数のインスタンスまで必要に応じてカートリッジの新しいインスタンスをイニシエートすることによってカートリッジの各々の実行を管理する。
【００６４】
たとえば、ある特定のカートリッジ（Ｃ１）のためのメタデータが以下の情報を含んでいると仮定する。
【００６５】
名称＝Ｃ１
最小インスタンス＝１０
最大インスタンス＝５０
ホストマシン＝Ｍ１、Ｍ３、Ｍ８
アイドルタイム＝３０秒
このメタデータに基づいて、カートリッジＣ１が初めに登録される際に、リソースマネージャ２５４はＣ１の１０のインスタンスをイニシエートさせる。リソースマネージャ２５４はラベルＭ１、Ｍ３およびＭ８に関連付けられるマシン上の１０のインスタンスをイニシエートすることになる。
【００６６】
Ｃ１をアクセスするリクエストをディスパッチャから受取った際、リソースマネージャ２５４はＣ１のいずれかの既存のインスタンスが利用可能であるかどうかを判定する。リクエストを受取った際にＣ１のどのインスタンスも利用可能でない場合、リソースマネージャ２５４はＣ１の最大数のインスタンスが既に実行されているかどうかを判定する。Ｃ１の最大数のインスタンスが既に実行されていない場合、リソースマネージャ２５４は可能なホストマシンの１つの上でＣ１の新しいインスタンスをイニシエートし、リクエストを発行したディスパッチャにこの新しいインスタンスを識別するメッセージを送信する。Ｃ１の最大数のインスタンスが既に実行されている場合、リソースマネージャ２５４はリクエストを発行したディスパッチャに対し、その時点でそのリクエストを取扱うことができないことを示すメッセージを送る。
【００６７】
負荷の最適配分
この発明の一実施例によれば、リソースマネージャ２５４は１組の負荷の最適配分の規則を適用して、２つ以上の可能なホストマシンがある中、カートリッジのインスタンスをどこでイニシエートするかを定める。すなわち、上の例では、Ｍ１、Ｍ２およびＭ３はすべてカートリッジＣ１のインスタンスを実行することが可能である。Ｍ１、Ｍ２およびＭ３が同じ処理能力を有する場合、インスタンスを３つのマシンにわたって均等に分散するのが望ましいであろう。しかしながら、Ｍ１がＭ２およびＭ３の１０倍の処理力を有するなら、Ｃ１のインスタンスのすべてをある時点まではＭ１でイニシエートし、それからさらなるインスタンスをＭ１、Ｍ２およびＭ３の間で均等に分散させるのが望ましいであろう。
【００６８】
可能なマシンの間で負荷の最適配分を如何に行なうかを定める上でリソースマネージャ２５４を助けるため、各カートリッジに対して蔵置されるメタデータはさらなる詳細を含んでいてもよい。たとえば、メタデータは各マシンに対してインスタンスの別個の最小および最大数を特定してもよい。マシンごとの最小および最大値を、すべてのマシンに適用される最小および最大値の代わりにまたはそれと併せて用いてもよい。その場合リソースマネージャ２５４は、最大許容可能なインスタンスに対して現在実行されているインスタンスの比が最も低いマシンはどれかに基づいて、マシン間で新しいインスタンスを分散させることができる。
【００６９】
メタデータはまた、ある特定のカートリッジを実行できるマシンのための順序を特定してもよい。その順序においてＮ＋１の位置にあるマシンは、その順序においてＮ番目の位置にあるマシンが既にＮ番目のマシンで許容されるその最大数のインスタンスを実行している場合にだけカートリッジのインスタンスを実行するのに用いられる。
【００７０】
カートリッジインスタンスステータスの管理
この発明の一実施例によれば、リソースマネージャ２５４は作られたカートリッジインスタンスを管理するためステート情報を維持する。ステート情報には、インスタンスを識別し、そのインスタンスを実行するマシンを識別し、そのインスタンスが割当てられたリスナを識別するデータが含まれる。
【００７１】
図５には、このステート情報を蔵置するためリソースマネージャ２５４が維持し得る表５００が示される。表５００には、インスタンス列５０２、カートリッジ列５０４、リスナ列５０６およびマシン列５０８が含まれる。表５００の各行は別個のカートリッジインスタンスに対応する。所与のカートリッジインスタンスに対する行内で、カートリッジ列５０４はカートリッジインスタンスに関連づけられるカートリッジを識別し、インスタンス列５０２はそのカートリッジインスタンスのインスタンス番号を示す。たとえば、行５１０はカートリッジＣ１のインスタンスに対応する。このため、行５１０のカートリッジ列５０４はカートリッジＣ１を示す。行５１０のインスタンス列５０２は行５１０に関連づけられるカートリッジインスタンスがカートリッジＣ１のインスタンス１であることを示す。
【００７２】
リスナ列５０６は、ある行に関連づけられるカートリッジインスタンスが割当てられたリスナを示す。マシン列５０８は、ある行に関連づけられるカートリッジインスタンスが実行されているマシンを示す。たとえば、行５１０に関連づけられるカートリッジインスタンスはリスナ２１０に割当てられており、マシンＭ１上で実行されている。
【００７３】
リソースマネージャ２５４と同様に、各ディスパッチャはそのディスパッチャが設けられているリスナに割当てられたカートリッジインスタンスに対するステート情報を維持する。このようなステート情報はたとえば、図４に示されるような表４００において維持されてもよい。表５００と同様に、表４００にはそれぞれインスタンス番号およびカートリッジ識別子を保持するインスタンス列４０２およびカートリッジ列４０４が含まれる。しかしながら、表５００ではリソースマネージャ２５４によって割当てられるすべてのカートリッジインスタンスに対して１つずつエントリが含まれるのに対し、表４００では特定のリスナに割当てられたカートリッジインスタンスに対するエントリしか含まれない。たとえば、表４００は、表５００に列挙されたカートリッジインスタンスのうちリスナ２００に割当てられたもののみに対するエントリを含む。
【００７４】
インスタンス列４０２およびカートリッジ列４０４に加えて、表４００にはステータス列４０６が含まれる。各行に対し、ステータス列４０６はその行に関連づけられるインスタンスのステータスを示す値を保持する。たとえば、行４０８のステータス列４０６はカートリッジＣ１にインスタンス１が現在ビジーであることを示している。例示される実施例では、ステータス列４０６はカートリッジインスタンスがＢＵＳＹまたはＦＲＥＥのいずれかであることを示すフラグを保持する。カートリッジステータスの重要性について、リソースマネージャ２５４とディスパッチャ２１４および２２０とのオペレーションに関連して以下に説明する。
【００７５】
ディスパッチャとリソースマネージャとの相互作用
上述のように、ディスパッチャは特定のカートリッジに変更されたブラウザリクエストを送る必要がある際にリソースマネージャ２５４と通信する。この発明の一実施例によれば、ディスパッチャはまず、適当なカートリッジのインスタンスが（１）これに既に割当てられているかどうか、また（２）新しい変更されたブラウザリクエストを処理するのに利用可能であるかどうかを判定する。適当なカートリッジインスタンスがディスパッチャに既に割当てられており新しい変更されたブラウザリクエストを処理するのに現在利用可能である場合、ディスパッチャはリソースマネージャ２５４とさらに通信することなく、変更されたブラウザリクエストをカートリッジインスタンスへ転送する。
【００７６】
たとえば、仮想パスマネージャ２５０によればカートリッジＣ１が処理しなければならないブラウザリクエストをリスナ２１０が受取ったと仮定する。また、表４００がリスナ２１０に割当てられたカートリッジインスタンスの現在のリストおよびステータスを反映すると仮定する。リスナ２１０からブラウザリクエストを受取ると、ディスパッチャ２１４は表４００を調べてカートリッジＣ１のＦＲＥＥインスタンスがあるか探す。例示される表４００では、行４１０がカートリッジＣ１のインスタンス３が現在ＦＲＥＥであることを示している。したがって、ディスパッチャ２１４はさらにリソースマネージャ２５４と通信することなく変更されたブラウザリクエストを直接カートリッジＣ１のインスタンス３に転送する。変更されたブラウザリクエストを送ることに応答してディスパッチャ２１４は行４１０のステータス列４０６のステータス値をＢＵＳＹに変える。
【００７７】
リスナに現在利用可能である適当なカートリッジインスタンスが既に割当てられていない場合、カートリッジに関連づけられるディスパッチャはリソースマネージャ２５４からのカートリッジインスタンスをリクエストする。必要とされるカートリッジのインスタンスが利用可能でなく、かつ必要とされるカートリッジの既存のインスタンスの数が最大数より下であることをリソースマネージャ２５４が判定した場合、リソースマネージャ２５４は新しいカートリッジをイニシエートする。新しいカートリッジをイニシエートする際に、リソースマネージャ２５４は表５００に新しいカートリッジインスタンスのためのエントリを挿入する。
【００７８】
たとえば、カートリッジＣ３が処理しなければならないブラウザリクエストをリスナ２１０が受取ったと仮定する。また、カートリッジＣ３のインスタンス３がまだイニシエートされていないものと仮定する。こうした条件の下では、ディスパッチャ２１４はリソースマネージャ２５４にカートリッジＣ３のインスタンスに対するハンドルを求めるリクエストを送る。このリクエストに応答して、リソースマネージャ２５４はマシンＭ３上でカートリッジＣ３のインスタンス３をイニシエートする。さらに、リソースマネージャ２５４は行５１２に見られるエントリを表５００に挿入する。
【００７９】
表５００にカートリッジＣ３のインスタンス３のための行５１２を挿入した後、リソースマネージャ２５４はディスパッチャ２１４に新しく作られたインスタンスに対するハンドルを送り返す。このハンドルを受取ったことに応答して、ディスパッチャ２１４はそのステータス表４００に新しいインスタンスのためのエントリ（行４１２）を挿入する。ディスパッチャ２１４はそこで、変更されたブラウザリクエストをカートリッジＣ３のインスタンス３に送信する。
【００８０】
カートリッジインスタンスの解放
この発明の一実施例によれば、リスナはカートリッジインスタンスが未処理のブラウザリクエストに応答し終わった際にカートリッジインスタンスの所有権を自動的に解放することはない。たとえば、カートリッジＣ３のインスタンス３が変更されたブラウザリクエストを受取り、その変更されたブラウザリクエストを処理して、ディスパッチャ２１４に応答を送り返すと想定する。ディスパッチャ２１４はその応答をリスナ２１０に渡し、これがブラウザリクエストを発行したブラウザに送り返されるようにする。
【００８１】
この時点で、リスナ２１０はカートリッジＣ３のインスタンス３の所有権をもはや必要としない。しかしながら、カートリッジＣ３のインスタンス３の所有権をリソースマネージャ２５４に戻す代わりに、ディスパッチャ２１４は単に行４１２のステータス列４０６をＢＵＳＹからＦＲＥＥに変える。
【００８２】
行４１２のステータス列４０６の値をＦＲＥＥに変えることによって、カートリッジＣ３のインスタンス３がもはやリクエストを処理しておらず、よって後続のリクエストを処理する準備ができていることが示される。しかしながら、カートリッジＣ３のインスタンス３が利用可能であることを示す表４００はディスパッチャ２１４によって局所的に維持されているため、カートリッジＣ３のインスタンス３はリスナ２１０に到達する後続のブラウザリクエストに対してだけ利用可能である。リソースマネージャ２５４が維持する表５００の行５１２はカートリッジＣ３のインスタンス３をリスナ２１０が所有していることを引続き示す。
【００８３】
リスナはリクエストが処理されるたびにカートリッジインスタンスを自動的に解放するわけではないため、リソースマネージャ２５４とさまざまなディスパッチャとの間での通信に関連するオーバーヘッドは大幅に減少される。たとえば、カートリッジＣ３に伝えなければならない１０の連続したリクエストをリスナ２１０が受取るものと仮定する。１０のリクエストの各々に対してリソースマネージャ２５４と通信するのではなく、ディスパッチャ２１４は最初のリクエストに応答してリソースマネージャ２５４と通信してもよい。ディスパッチャ２１４は後続の９つのリクエストをリソースマネージャ２５４と通信することなく処理することができるが、これはディスパッチャ２１４が最初のリクエストを処理するＣ３の同じインスタンスを用いて９つの後続のリクエストを処理するためである。
【００８４】
各リクエストを処理する際にカートリッジインスタンスのリスナ所有権を自動的に解放しないことでウェブアプリケーションサーバ２８０の効率が向上されるとはいえ、リスナは無期限にカートリッジインスタンスの所有権を維持することはできない。たとえば、長い期間にわたって用いられなかったインスタンスはリソースマネージャ２５４に戻され、リソースを空けるためにその割当ての解除ができるようにすべきである。さらに、他のリスナがそのカートリッジのインスタンスを必要としているところに、１つのリスナが比較的長い時間使っていなかったカートリッジのインスタンスの所有権を維持することは効率的ではない。
【００８５】
したがって、リソースマネージャ２５４は、リスナに渡される各カートリッジインスタンスのための最大アイドルタイムを各リスナに伝える。最大アイドルタイムとは、リスナがカートリッジインスタンスの所有権を解放しなければならなくなる前にそのカートリッジインスタンスが使用されない状態でいられる最大の時間を示すものである。たとえば、カートリッジＣ３のインスタンス３のための最大量のアイドルタイムが１０分であることをリソースマネージャ２５４がリスナ２１０に示すものと仮定する。この情報に基づいて、リスナ２１０は、カートリッジＣ３のインスタンス３が１０分より長い間アイドル状態またはＦＲＥＥとならない限りにおいてカートリッジＣ３のインスタンス３を続けて用いてカートリッジＣ３に対するブラウザリクエストを処理することができる。
【００８６】
カートリッジＣ３のインスタンス３が１０分より長い間アイドル状態である場合、ディスパッチャ２１４は表４００から行４１２を取除き、リスナ２１０がカートリッジＣ３のインスタンス３の所有権を解放することをリソースマネージャ２５４にメッセージを送って知らせる。このメッセージに応答して、リソースマネージャ２５４は行５１２を更新して、カートリッジＣ３のインスタンス３がいずれのリスナによっても所有されておらず、よって別のリスナに再割当てされるか終了され得ることを示す。
【００８７】
代替の実施例では、カートリッジインスタンスのためのアイドルタイムが満了した際にもディスパッチャはカートリッジインスタンスを自動的に解放しない。代わりに、ディスパッチャはリソースマネージャ２５４にメッセージを送り、満了となったインスタンスを解放することを申し出る。リソースマネージャ２５４はこの申し出に応答して、リスナがカートリッジインスタンスを解放するようリクエストするか、またはリスナがその満了となったカートリッジインスタンスの所有権を持ち続けることを許可してもよい。
【００８８】
この発明の一実施例によれば、リソースマネージャ２５４は直ちに処理することのできないリクエストのキューを維持する。キュー内のリクエストを処理することが可能となると、そのリクエストはキューから取除かれ処理される。
【００８９】
たとえば、カートリッジＣ１が処理しなければならないブラウザリクエストをリスナ２２２が受取り、そのリスナ２２２にカートリッジＣ１のいずれのインスタンスも割当てられていなかったと仮定する。ディスパッチャ２２６はリソースマネージャ２５４にＣ１のインスタンスに対するリクエストを送る。さらに、Ｃ１の最大５０のインスタンスが許容され、Ｃ１の５０のインスタンスがリスナ２１０に割当てられたと仮定する。こうした条件の下では、リソースマネージャ２５４はリスナ２２２からのリクエストを処理することができない。このため、リソースマネージャ２５４はそのリクエストをキューにおく。リスナ２１０がＣ１のインスタンスを解放すると、リソースマネージャ２５４はリスナ２２２にＣ１のインスタンスが利用可能であることを伝える。
【００９０】
ある特定の条件の下で、リソースマネージャ２５４は強制的にリスナにカートリッジインスタンスを解放させることがある。たとえば、リソースマネージャ２５４はシステムオーバロード状況を検出し、これに応答して１組のカートリッジインスタンスを終了することがあり、これはそのカートリッジインスタンスが終了されることになることをそのカートリッジインスタンスが現在割当てられているリスナに知らせる前または知らせた後に行なわれる。
【００９１】
また、リソースマネージャ２５４はリスナの間での公平性の方針を実現するために強制的にリスナにカートリッジインスタンスを解放させることがある。たとえば、別のリスナが予め定められたしきい値より長い時間にわたってカートリッジのインスタンスを待っている場合、リソースマネージャ２５４は所与のカートリッジの最も多い数のインスタンスを保持するリスナにそのカートリッジのあるインスタンスを解放させてもよい。たとえば、リスナ２１０にカートリッジＣ１の５０のインスタンスが割当てられ、Ｃ１は最大で５０のインスタンスを有する場合、リソースマネージャ２５４は別のリスナからＣ１のインスタンスに対するリクエストを受取ってから１０秒後にリスナ２１０にＣ１のあるインスタンスを解放させてもよい。
【００９２】
カートリッジ実行エンジン
この発明の一実施例によれば、各カートリッジインスタンスはカートリッジ実行エンジンおよびカートリッジから構成される。カートリッジ実行エンジンは、マシン間通信機構およびウェブアプリケーションサーバ２８０の複雑さからカートリッジを隔離するコードモジュールである。カートリッジは、関数テーブルにカートリッジ関数に対するポインタを蔵置することによってカートリッジ実行エンジンに利用可能となる。一実施例によれば、すべてのカートリッジが、上述の例示のカートリッジインターフェイスにおいて特定された関数を提供する。すべてのカートリッジが同じインターフェイスをサポートするようにさせることにより、単一の標準カートリッジ実行エンジンをすべてのカートリッジに対して用いることができる。
【００９３】
この発明の一実施例によれば、カートリッジは共用ライブラリとして実装され、カートリッジ実行エンジンは標準カートリッジインターフェイスを用いて共用ライブラリ内のルーチンを呼出す実行可能なプログラムである。カートリッジ実行エンジンはカートリッジとディスパッチャとの間でインターフェイスをもたらし、カートリッジの制御のフローを指示し、カートリッジが用いるサービスを提供する。
【００９４】
リソースマネージャ２５４が新しいカートリッジインスタンスの生成を必要とする場合、リソースマネージャ２５４はカートリッジ実行エンジンのインスタンスを生成させる。これに対し、このようにして作られたカートリッジ実行エンジンのインスタンスは適当なカートリッジのインスタンスを生成させる。リソースマネージャ２５４はたとえば、カートリッジが実行されるマシン上にある「カートリッジ実行エンジンファクトリ」と呼出すことによってカートリッジ実行エンジンのインスタンスを生成させることができる。カートリッジ実行エンジンのインスタンスはたとえば、そのカートリッジを構成する共用ライブラリ内のルーチンのうちの１つに呼出を行なうことによってカートリッジのインスタンスを生成させることができる。
【００９５】
図２に示されるように、ウェブアプリケーションサーバ２８０はカートリッジ２３０、２３４および２３８の各々に対しカートリッジ実行エンジン２２８、２３２および２３６を含む。カートリッジ実行エンジンは標準のカートリッジインターフェイスを介してカートリッジへの呼出を行なうことにより対応するカートリッジの実行を制御する。以下に述べるように、カートリッジ実行エンジンとカートリッジとの間で基本的なコールバック機能を確立することにより、そのカートリッジをコールバック機能に応答するよう構成し、次にそのカートリッジをコンフィギュレーションプロバイダ２５６に登録することによってどんなカートリッジもウェブアプリケーションサーバ２８０に統合することができる。
【００９６】
したがって、ＰＬ／ＳＱＬランタイムカートリッジがリクエストを処理するのに適当なカートリッジであるとディスパッチャ２１４が判定すると、ディスパッチャ２１４はそのＰＬ／ＳＱＬランタイムカートリッジに関連づけられるカートリッジ実行エンジンを含むカートリッジインスタンスにそのリクエストをディスパッチする。新しいインスタンスをイニシエートする必要がある場合、リソースマネージャ２５４は別個のアドレス空間においてＰＬ／ＳＱＬランタイムカートリッジの新しいインスタンスを作り、その新しいインスタンスのカートリッジ実行エンジン２２８へそのリクエストをディスパッチする。プログラムのインスタンスを実行するのに用いられるアドレス空間は、ウェブアプリケーションサーバ２８０の構成要素の１つ以上が実行されているコンピュータシステムのメモリ内にあるか、または別のコンピュータシステム上にあってもよい。
【００９７】
ディスパッチャからのメッセージに応答して、カートリッジ実行エンジンはカートリッジにリクエストハンドラコールバック機能を発行し、カートリッジにそのリクエストを処理させる。そのリクエストを処理するカートリッジはその結果をカートリッジ実行エンジンに返し、カートリッジ実行エンジンはその結果をディスパッチャに転送する。ウェブアプリケーションサーバ２８０がオペレーションにおいて障害を検出した場合にはカートリッジ実行エンジンはカートリッジのシャットダウン関数を発行する。
【００９８】
このように、カートリッジ実行エンジンは、実行すべき予め定められたオペレーションを特定するウェブアプリケーションサーバ２８０へのアプリケーションプログラミングインターフェイスを提供する。標準のカートリッジインターフェイスを使用することにより、カートリッジのプログラマが、カートリッジがともに用いられることになる特定のウェブリスナが用いるプロトコルとは無関係に、各カートリッジをウェブアプリケーションサーバ２８０へ高レベルで統合化するよう構成することができる。
【００９９】
トランスポートアダプタ
リスナは、サーバ側のプラグインが使用するためのプログラミングインターフェイスおよびプロトコルを提供することによってそのようなプラグインの使用を可能にする。残念なことに、リスナが提供するプログラミングインターフェイスおよびプロトコルはリスナごとに異なる。たとえば、ネットスケープ・サーバ・アプリケーション・プログラミング・インターフェイス（ＮＳＡＰＩ：Netscape Server Application Programming Interface）、インターネット・サーバ・アプリケーション・プログラミング・インターフェイス（ＩＳＡＰＩ：Internet Server Application Programming Interface）およびアプリケーション開発インターフェイス（ＡＤＩ：Application Development Interface）は現在リスナによりもたらされる別個のプログラミングインターフェイスの３つの例である。
【０１００】
トランスポートアダプタはウェブリスナが用いる私的プロトコルおよびインターフェイスからディスパッチャを隔離する。特定的には、各トランスポートアダプタはさまざまなリスナのプロトコルを認識し、リスナから受取ったブラウザリクエストを変換してリスナのプロトコルとは無関係の標準ディスパッチャプロトコルを有する変換されたブラウザリクエストを生じるよう構成される。同様に、トランスポートアダプタはディスパッチャからの返答をリスナのトランスポートプロトコルに変換する。
【０１０１】
このように、トランスポートアダプタにより、ウェブアプリケーションサーバ２８０を異なるベンダのリスナとともに用いることが可能となる。さらに、トランスポートアダプタは異なるサーバアーキテクチャおよびオペレーティングシステムに対応するよう構成されてもよい。
【０１０２】
ウェブアプリケーションサーバのオペレーション
図３Ａおよび図３Ｂはこの発明の一実施例によるブラウザリクエストに応答する方法を示すフロー図である。ステップ３５０においてリスナがブラウザリクエストを受取る。説明のために、このブラウザリクエストはブラウザ２０２により発行されリスナ２１０により受取られるものと仮定する。
【０１０３】
ブラウザリクエストを受取ると、リスナ２１０はステップ３５２においてウェブアプリケーションサーバ２８０にそのリクエストを転送する。特定的には、リスナ２１０はリスナ２１０の私的プログラミングインターフェイスを用いてそのリクエストをトランスポートアダプタ２１２に渡す。トランスポートアダプタ２１２は、必要に応じてそのリクエストを標準ディスパッチャプログラミングインターフェイスを用いて変換しそのリクエストをディスパッチャ２１４に渡す。
【０１０４】
ディスパッチャ２１４は、仮想パスマネージャ２５０と通信することによって、ブラウザリクエストにより特定される仮想パスに基づいて、ステップ３５４においてブラウザリクエストに対応するリクエストオブジェクトタイプを識別する。リクエストのオブジェクトタイプがカートリッジに対応するものであれば、仮想パスマネージャは、認証が必要であるか否かもディスパッチャ２１４に示す。
【０１０５】
ディスパッチャ２１４はステップ３５６において、そのリクエストオブジェクトタイプが識別可能なカートリッジに対応するかどうかを判定する。そのリクエストオブジェクトタイプが識別可能なカートリッジに対応していない場合、そのリクエストはステップ３５８においてリスナ２１０に戻される（図３Ｂを参照）。ステップ３５８においてそのリクエストが静的ＨＴＭＬページに対するリクエストであることをリスナ２１０が認識すると、リスナはその静的ＨＴＭＬページにアクセスし、そのＨＴＭＬページをステップ３６０においてブラウザ２０２に送る。ブラウザリクエストがリスナ２１０によって認識されない場合、ステップ３６０において返答がブラウザ２０２に送られそのリクエストが認識不可能であったことを示す。
【０１０６】
ステップ３５６において、リクエストをカートリッジに送らなければならないことをディスパッチャ２１４が判定すると、ディスパッチャは認証サーバ２５２と通信することにより、何らかの必要な認証を行なう。この認証プロセスについては後により詳細に述べる。さらに、ステップ３５６で、現在ＦＲＥＥであるカートリッジのどのインスタンスにもリスナ２１０が割り当てられていない場合、ディスパッチャ２１４は、そのブラウザリクエストを送ることのできるカートリッジ２３０のインスタンスが割当てられることになるリソースマネージャ２５４と通信する。
【０１０７】
図３Ｂに示されるステップ３６２では、リソースマネージャ２５４は、識別されたカートリッジのインスタンスが既存のインスタンスの数の中で利用可能である（所有されていない）かどうかを判定する。説明のため、このリクエストはカートリッジ２３０に関連づけられるものであり、カートリッジ２３０はＰＬ／ＳＱＬランタイムカートリッジであると仮定する。
【０１０８】
ステップ３６２においてリソースマネージャが利用可能なインスタンス、たとえばＰＬ／ＳＱＬランライム２３０のインスタンス２６０を識別すると、リソースマネージャ２５４はリクエストをインスタンス２６０に送るべきであることをディスパッチャ２１４に知らせる。ディスパッチャ２１４はそこで、変更されたブラウザリクエストを作りステップ３６８においてインスタンス２６０のカートリッジ実行エンジン２２８にその変更されたブラウザリクエストを送って、以下に説明するように利用可能なインスタンス２６０にそのリクエストを処理させる。
【０１０９】
しかしながら、ステップ３６２においてカートリッジ２３０のインスタンスが１つも利用可能でない場合、リソースマネージャ２５４はステップ３６４において、既存のインスタンスの数が最大所定数を超えるかどうかを判定する。ステップ３６４において既存のインスタンスの数が最大所定数を超える場合、リソースマネージャ２５４はその時点ではそのリクエストを処理できないことをディスパッチャ２１４に示す。これに応答して、ディスパッチャ２１４はステップ３５８においてそのリクエストをリスナ２１０に返し、その後に、ウェブリスナ２１０はステップ３６０においてネットワークを介してブラウザ２０２へ返答を送り、そのリクエストが処理されなかったことを示す。
【０１１０】
代わりに、カートリッジインスタンスがリクエストを処理するためにその現時点で利用可能でない場合、リスナ２１０はそのカートリッジインスタンスに対する待ちリストにそのリクエストを入れてもよい。カートリッジインスタンスが利用可能となると、変更されたブラウザリクエストが待ちリストから取除かれカートリッジインスタンスに転送される。変更されたブラウザリクエストが予め定められた時間より長い間待ちリストに残っている場合、リスナ２１０はそのリクエストを待ちリストから取除いてブラウザ２０２にメッセージを送りそのリクエストが処理できなかったことを示すようにしてもよい。
【０１１１】
ステップ３６４において既存のインスタンスの数が最大所定数を超えない場合、リソースマネージャ２５４は識別されたプログラムの新しいインスタンスをイニシエートし、ブラウザリクエストに基づく変更されたブラウザリクエストを新しいインスタンスに送るべきであることをディスパッチャ２１４に知らせる。そこでディスパッチャ２１４は変更されたブラウザリクエストをその新しいインスタンスのカートリッジ実行エンジンへディスパッチする。
【０１１２】
たとえば、リソースマネージャ２５４がブラウザリクエストに応答してインスタンス２６０をイニシエートしたと仮定する。その初期化の間、ＰＬ／ＳＱＬランタイムのための蔵置された命令シーケンスにアクセスが行なわれ、ディスパッチャ２１４が実行しているアドレス空間とは別個のアドレス空間においてカートリッジ２３０の新しいインスタンス２６０が作られる。一実施例によれば、初期化はカートリッジ実行エンジン２２８をロードし、そのカートリッジ実行エンジンにカートリッジ２３０内の初期化ルーチンを呼出させることによって行なわれる。
【０１１３】
一度新しいインスタンス２６０が実行されると、ディスパッチャ２１４はステップ３６８においてその新しいインスタンス２６０に関連づけられているカートリッジ実行エンジン２２８にリクエストをディスパッチする。カートリッジ実行エンジン２２８は新しいインスタンス２６０にコールバックメッセージを送りそのリクエストの実行を要求する。そのコールバックメッセージにおいて、カートリッジ実行エンジン２２８はそのリクエストを処理する上でインスタンス２６０が必要とする全てのパラメータを渡す。このようなパラメータにはたとえば、パスワード、データベース探索キー、またはインスタンス２６０が実行する動的オペレーションのための他のどんな引き数を含んでいてもよい。
【０１１４】
次にインスタンス２６０はリクエストを実行する。ステップ３６８におけるインスタンスによるリクエストの実行の間、ディスパッチャ２１４はステップ３７０においてインスタンスを監視して障害が発生するかどうかを判定する。ステップ３７０においてディスパッチャ２１４が障害を検出すると、ディスパッチャ２１４はステップ３７２において対応するカートリッジ実行エンジン２２８を呼出し、その障害を有するインスタンス２６０を打ち切る。これに対し対応するカートリッジ実行エンジン２２８はＡＰＩを通して障害のあるインスタンスに対してシャットダウンコマンドを発行する。そのインスタンスはカートリッジ実行エンジン２２８によるシャットダウンコマンドに応答して、他のどんなアドレス空間における他のどんなプロセスにも影響を与えることなくシャットダウンする。
【０１１５】
ステップ３７０において障害が検出されない場合、ディスパッチャ２１４はステップ３７４において実行の完了の際にインスタンス２６０から返答を受取る。ステップ３７６においてディスパッチャ２１４はその返答をリスナ２１０に転送し、リスナ２１０は実行されたインスタンス２６０からの返答をもってブラウザに応答する。インスタンス２６０を実行した後、ステップ３７８においてディスパッチャ２１４はステップ３７８に示されるようにメモリ内にインスタンスを維持し、後続のリクエストの実行を可能にする。
【０１１６】
ウェブサーバの分散アーキテクチャ
重要なことであるが、ウェブアプリケーションサーバ２８０のさまざまな構成要素は、それら構成要素が同じアドレス空間において実行される必要がなく同じマシン上で実行されることさえ必要としない通信機構を用いて互いに通信する。例示される実施例では、ウェブアプリケーションサーバ２８０の構成要素はオブジェクトリクエストブローカ（ＯＲＢ：Object Request Broker）２８２を介して通信するよう構成される。オブジェクトリクエストブローカは「共通オブジェクトリクエストブローカ：アーキテクチャおよび仕様（ＣＯＲＢＡ）」（"Common Object Request Broker: Architecture and Specification (CORBA)"）に詳しく記載されている。ＣＯＲＢＡに関連するこのおよび他の文献はワールド・ワイド・ウェブのhttp://www.omg.orgにおいて見つけることができる。
【０１１７】
この発明の実施例はＣＯＲＢＡに従ったＯＲＢを介する通信に関連して説明するが、他のクロスプラットフォーム通信機構を用いてもよい。たとえば、ウェブアプリケーションサーバ２８０の構成要素は代わりに、遠隔手続き呼出（ＲＰＣ：Remote Procedure Calls）、ＵＮＩＸパイプ、Microsoft COMを用いて互いに通信してもよい。
【０１１８】
ウェブアプリケーションサーバ２８０のさまざまな構成要素がマシンから独立した通信機構を用いて互いに通信するため、構成要素が互いに対してどこに存在するかということに関して固有の制約はない。たとえば、リスナ２１０、２１６および２２２は同じマシン上で実行していてもよく、またはそれぞれがこのようなオペレーティングシステムを有する３つの完全に異なったマシン上で実行してもよい。同様に、認証サーバ２５２、仮想パスマネージャ２５０、リソースマネージャ２５４およびコンフィギュレーションプロバイダ２５６は同じマシン上で実行していてもよく、または４つの異なるマシン上で実行していてもよい。さらに、これらの４つの異なるマシンはリスナ２１０、２１６および２２２を実行する３つのマシンと少しも重複していなくてもよい。
【０１１９】
カートリッジ実行エンジン２２８、２３２および２３６は、オブジェクトリクエストブローカ２８２を介してウェブアプリケーションサーバ２８０の他の構成要素と通信するのに必要な論理のすべてを組込んでいる。したがって、カートリッジインスタンス自体の場所は通信機構によって本質的に制約されるものではない。すなわち、インスタンス２６０はこれがリクエストを受取るディスパッチャとは全く異なるマシンおよびオペレーティングシステムにおいて実行されてもよい。同様に、インスタンス２６０は、リソースマネージャ２５４、または同じウェブアプリケーションサーバ２８０によって管理される他のカートリッジのインスタンスを含む、ウェブアプリケーションサーバ２８０の他の構成要素のいずれとも異なるマシンおよびオペレーティングシステム上にあってもよい。
【０１２０】
重要なことだが、ウェブアプリケーションサーバ２８０が用いるカートリッジが享受する場所の独立性は、カートリッジそのものにおける何らかのカスタムプログラミングを介してではなくカートリッジ実行エンジンの通信論理を介して達成される。したがって、分散アプリケーションサーバ環境における実行のために特別にカートリッジを設計する必要がない。このように、カートリッジ設計者らは分散システムの複雑さから隔離され、カートリッジが作られる目的であるタスクと関連する論理に労力を集中させることができる。
【０１２１】
トランザクションの処理
本発明の一実施例によれば、トランザクションは、特定のタイプのトランザクションについての特定の情報を示すメタデータを用いることにより、ステートレスな環境において実現される。メタデータ中に供給されたトランザクションについての情報は、ここではトランザクションの属性と呼ばれる。トランザクションの特定の属性を示すためにメタデータを用いることにより、ステート情報を持続的に維持するためにカートリッジを必要としないシステムが可能となる。そのようなシステム中のトランザクションは、プログラム型ではなく宣言型であり、メッセージ自体がそれらの所属するトランザクションを示すというものである。たとえば、２つの特定のタイプのトランザクションについてのメタデータ、ＴＸ１およびＴＸ２は、以下のとおりであり得る。
【０１２２】
0004729172.tif 000003
トランザクションの各タイプに対して、メタデータはさまざまな属性を含む。一実施例に従うと、属性は、カートリッジ名、トランザクション名、所属先リスト（ｂｅｌｏｎｇ−ｔｏ−ｌｉｓｔ）、リソースリスト（ｒｅｓｏｕｒｃｅ−ｌｉｓｔ）、開始（ｂｅｇｉｎ）、コミット（ｃｏｍｍｉｔ）、およびロールバック（ｒｏｌｌｂａｃｋ）ＴＲＡＮＳＡＣＴＩＯＮ  ＵＲＬを含む。上記の例では、ＴＸ１のカートリッジ名はＳＴＯＲＥＦＲＯＮＴであり、トランザクション名はＳＴＯＲＥＡＣＣＯＵＮＴＳであり、所属先リストは／ＳＴＯＲＥＦＲＯＮＴおよび／ＢＡＮＫＩＮＧを含み、リソースリストは／ＳＥＡＲＳおよび／ＢＡＮＫ１を含み、開始トランザクションＵＲＬは／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ  ｓｅｓｓｉｏｎであり、コミットトランザクションＵＲＬは／ｓｔｏｒｅｆｒｏｎｔ／ｃｏｍｍｉｔ  ｓｅｓｓｉｏｎであり、さらに、ロールバックトランザクションＵＲＬは／ｓｔｏｒｅｆｒｏｎｔ／ｒｏｌｌｂａｃｋ  ｓｅｓｓｉｏｎである。
【０１２３】
カートリッジ名の属性は、トランザクションのオペレーションを実行するためにディスパッチャが通信する特定のタイプのカートリッジを識別する。トランザクション名の属性は、他のトランザクションのタイプと関連するトランザクションのタイプを一意に識別する。あるトランザクションタイプの所属先リストは、そのトランザクションのオペレーションに関与し得るカートリッジをリストする。リソースリストは、、そのトランザクションタイプのトランザクションのオペレーションによって影響されるリソースのリストである。開始トランザクションＵＲＬは、このタイプのトランザクションが開始されようとしていることを知らせるＵＲＬである。コミットトランザクションＵＲＬは、現在進行中のこのタイプのトランザクションがコミットされるべきであることを知らせるＵＲＬである。ロールバックトランザクションＵＲＬは、既に始まっているこのタイプのトランザクションがロールバックされるべきであることを示すＵＲＬである。トランザクションの実行中にこれらの属性値の各々がいかに使用されるかについては、以下により詳細に述べる。
【０１２４】
トランザクションの概要
図６は、本発明の一実施例によるステートレスな環境における複数リクエストトランザクションの処理を提供する、システム６００のブロック図である。図６は図２と類似しているので、同様の構成要素には同じ番号が付されている。この文書中では、ブラウザリクエストという用語とトランザクションリクエストという用語は、互換的に用いられる。複数リクエストのトランザクションという用語は、２以上のブラウザリクエストを含む単一のトランザクションのことを指すのに用いられる。
【０１２５】
カートリッジ実行エンジン２２８は、ブラウザリクエストを受取るために、オブジェクトリクエストブローカ２８２を通じて複数のディスパッチャ（たとえば１以上のディスパッチャ２１４、２２０および２２６）と通信する。これらのブラウザリクエストは、インターネット２０８に接続された複数のブラウザから送られ得る。複数のディスパッチャに加えて、カートリッジ実行エンジン２２８は、カートリッジ２３０、コンフィギュレーションプロバイダ２５６およびトランザクションマネージャ６０６とも通信する。上述したように、カートリッジ２３０は、明確に定義された関数を実行するカートリッジとして、またはアプリケーションに対するインタープリタまたはルーチン環境として作動するプログラマブルカートリッジとしてかのいずれかで構成される、コードのモジュールを表わす。カートリッジ実行エンジン２２８、トランザクションマネージャ６０６およびカートリッジ２３０の組合せは、カートリッジインスタンスを構成する。
【０１２６】
特定のカートリッジは、複数のデータベースにアクセスするために複数のデータベースサーバと関連づけられ得る。この例では、カートリッジ２３０は、データベースサーバ６０８およびデータベースサーバ６１２のそれぞれを通じてデータベース６１０およびデータベース６１４にアクセスすることにより、ＳＱＬ（Structured Query Language）に従って、データベーストランザクションを処理する能力を有する。
【０１２７】
トランザクションマネージャ６０６は、カートリッジ実行エンジン２２８と関連づけられる調整モジュールを表わし、ステートレスなウェブ環境における複数リクエストトランザクションの実行を調整するように機能する。複数リクエストトランザクションの実行の調整において、トランザクションマネージャ６０６は複数リクエストトランザクションに対していかなるステート情報も保持しない。トランザクションマネージャ６０６はカートリッジ実行エンジン２２８と通信して、トランザクション制御メッセージを受取る。トランザクション制御メッセージに含まれる情報を用いて、トランザクションマネージャ６０６はデータベースサーバ６０８および６１２と相互作用し、複数リクエストトランザクションの間にそれぞれのデータベース６１０および６１４に対してなされた変更を、作業のアトミック単位としてコミットまたはロールバックさせる。
【０１２８】
トランザクションの識別
複数リクエストトランザクションと関連づけられるブラウザリクエストは、グローバルに一意のトランザクションＩＤを含む。ブラウザリクエスト内のグローバルに一意のトランザクションＩＤは、このブラウザリクエストが所属している複数リクエストトランザクションを識別するために用いられる。一実施例によると、開始トランザクションＵＲＬを含むブラウザリクエストを受けると、トランザクションマネージャはグローバルに一意のトランザクションＩＤを作成する。このグローバルに一意のトランザクションＩＤは送信ブラウザに戻され、同じ複数リクエストトランザクションと関連した後続のブラウザリクエストのブラウザによって送られる。
【０１２９】
特定の実施例においては、複数リクエストトランザクションが開始されたブラウザに戻されると、特定の複数リクエストトランザクションに関連づけられるグローバルに一意なトランザクションＩＤは、ブラウザを実行するクライアントのクッキー情報として蔵置される。後続のブラウザリクエストがブラウザから送られると、ディスパッチャは、後続のリクエストが開始トランザクションＵＲＬを含むか否かを判定する。このリクエストが開始トランザクションＵＲＬを含まなければ、ディスパッチャは、ＨＴＴＰプロトコル標準を用いて送信ブラウザのクッキー情報を読出すことによってブラウザリクエストに関連づけられる、グローバルに一意のトランザクションＩＤを獲得する。
【０１３０】
たとえば、ブラウザ２０２がトランザクションに関連づけられる第１のブラウザリクエストおよび開始トランザクションＵＲＬを送信すると、トランザクションマネージャ６０６は一意のブラウザ識別子を作成し、それをディスパッチャ２１４に送る。ディスパッチャ２１４は次いで、グローバルに一意のトランザクションＩＤをブラウザ２０２におけるクッキー情報として蔵置する。ブラウザ２０２が同じトランザクションと関連づけられている第２のブラウザリクエストを送信すると、ディスパッチャ２１４はブラウザ２０２のクッキー情報に含まれるグローバルに一意のトランザクションＩＤを獲得する。
【０１３１】
グローバルに一意のトランザクションＩＤを用いて、ブラウザリクエストを最終的に処理するデータベースサーバは、第１のブラウザリクエストおよび第２のブラウザリクエストの両方が同じ複数リクエストトランザクションに関連づけられていると判定することができる。特定の実施例においては、特定のブラウザが、一度に１以上のトランザクションを実行することができるので、その特定のトランザクションのカートリッジ名はグローバルに一意のトランザクションＩＤの各々内に含まれ、グローバルに一意のトランザクションＩＤが対応している特定のトランザクションの識別を助けるために用いられる。
【０１３２】
特定の状況においては、特定のブラウザでクッキー情報が使用できない場合もある。たとえば、特定のブラウザはクッキーの使用をサポートしない場合もあり、または特定のユーザがブラウザのクッキー情報へのアクセスを拒絶すると選択する場合もある。したがって、特定の実施例では、トランザクション識別子はブラウザに戻されたメッセージ内に埋込まれ、後続のブラウザリクエストにおいてブラウザによって送信される。これは、ブラウザ２０２に戻されるＨＴＭＬページのハイパーリンクと関連づけられているＵＲＬに注釈をつけることにより、達成できる。ブラウザリクエストＵＲＬの一部として送信されたグローバルに一意のトランザクションＩＤに基づいて、ブラウザリクエスト中で特定されたオペレーションを最終的に実行するデータベースサーバは、グローバルに一意のトランザクションＩＤを用いて特定のブラウザリクエストの各々が所属している複数リクエストトランザクションを識別することができる。
【０１３３】
トランザクションカートリッジのインスタンス生成
各ブラウザリクエストは、ＨＴＭＬページのハイパテキストリンクを選択するブラウザのユーザに応答して送信ブラウザから送信されるＵＲＬ情報を含む。ＵＲＬ情報は、ＵＲＩ（Uniform Resource Indicator）部分とヘッダ部分とを含む。ＵＲＩ部分はトランザクションのステート情報およびカートリッジ名を含む。トランザクションのステート情報は、複数リクエストトランザクションの特定のステートを識別するのに用いられる。カートリッジ名は、カートリッジのタイプを識別するのに用いられ、カートリッジ実行エンジンがブラウザリクエストに関連づけられているメタデータを識別できるようにする。
【０１３４】
ヘッダ部分は、特定のトランザクションリクエストに関連づけられている複数リクエストトランザクションを識別するためにデータベースサーバによって用いられる、グローバルに一意のトランザクションＩＤを蔵置するために用いられる。
【０１３５】
リスナはブラウザリクエストを受けると、そのブラウザリクエストをディスパッチャに伝達する。ディスパッチャはその後、仮想パスマネージャと通信してブラウザリクエストに関連づけられるカートリッジのタイプを決定する。一実施例では、ディスパッチャはＵＲＩ内に含まれる情報を仮想パスマネージャに送る。ＵＲＩ内の情報を用いて、仮想パスマネージャはコンフィギュレーションプロバイダと通信し、ブラウザリクエストと関連づけられているカートリッジのタイプを決定する。
【０１３６】
一旦カートリッジのタイプが識別されると、仮想パスマネージャはカートリッジのタイプを識別するデータをディスパッチャに戻す。ディスパッチャはその後、特定のディスパッチャと前に関連づけられていたカートリッジインスタンスに対するポインタを含むカートリッジインスタンスポインタリストをサーチする。ディスパッチャがブラウザリクエストと関連づけられているカートリッジタイプのものであるカートリッジインスタンスに対するポインタの場所を突き止めると、ディスパッチャはこのポインタを用いて変更されたブラウザリクエストをカートリッジインスタンスに送信する。
【０１３７】
ディスパッチャがブラウザリクエストに関連づけられているカートリッジインスタンスのタイプに対するポインタの場所を突き止めなければ、ディスパッチャはリソースマネージャと通信してそのタイプのカートリッジインスタンスを獲得する。カートリッジインスタンスを獲得する際に、ディスパッチャは仮想パスマネージャによって前に識別されたカートリッジのタイプを含むリソースマネージャにメッセージを送る。
【０１３８】
ディスパッチャメッセージを受取ると、リソースマネージャはこのリクエストタイプのカートリッジインスタンスが使用できるか否かをカートリッジインスタンスポインタテーブルをサーチすることによって判定する。このリクエストタイプのカートリッジインスタンスポインタがカートリッジインスタンスポインタテーブル中で見付けられると、リソースマネージャは使用可能なカートリッジインスタンスに対するポインタをディスパッチャに送って戻す。
【０１３９】
しかしながら、このリクエストタイプのカートリッジインスタンスが使用できない場合、リソースマネージャはこのリクエストタイプのカートリッジのインスタンスが生成されるようにする。本発明の一実施例では、リソースマネージャは、特定のカートリッジファクトリプロセスをリクエストしてリクエストタイプのカートリッジインスタンスを作成することにより、そのリクエストタイプのカートリッジインスタンスを生成する。カートリッジファクトリプロセスは複数の機器にわたって位置づけられ得る。カートリッジインスタンスを生成するために特定のカートリッジファクトリプロセスがリクエストされると、それはカートリッジファクトリが現在実行されているものと同じマシン上でカートリッジインスタンスを生成する。したがって、リソースマネージャはリソースマネージャがカートリッジインスタンスの生成のために選択する特定のマシンに基づいて、どのカートリッジファクトリを用いるかを選択する。
【０１４０】
カートリッジインスタンスを生成するためのリクエストを受取ると、カートリッジファクトリプロセスはカートリッジ実行エンジンのインスタンスを生成する。一旦カートリッジ実行エンジンが生成されると、カートリッジ実行エンジンはリクエストされたカートリッジのタイプに関連づけられているトランザクション情報を（存在すれば）獲得する。たとえば、リクエストされたカートリッジのタイプが上記のＴＸ１に記載されるようなＳＴＯＲＥＦＲＯＮＴタイプであれば、カートリッジ実行エンジンはＴＸ１と関連づけられたメタデータ情報を獲得し、蔵置する。このメタデータ情報はトランザクションを処理するためにカートリッジのインスタンスによって用いられる。
【０１４１】
メタデータ情報の獲得後、カートリッジ実行エンジンはリクエストされたカートリッジタイプのカートリッジを生成する。作成されたカートリッジのインスタンスはカートリッジ実行エンジンと動的にリンクする。カートリッジ実行エンジンは次いで、トランザクションマネージャをインスタンス生成する。トランザクションマネージャのインスタンスは、カートリッジおよびカートリッジ実行エンジンと動的にリンクされ、カートリッジインスタンスを形成する。
【０１４２】
一旦カートリッジインスタンスが形成されると、トランザクションマネージャはカートリッジ実行エンジンによって前に蔵置されていたメタデータ情報を用いて、メタデータのリソースリスト中で特定されたデータベースとのコネクションを開く。これらのコネクションはトランザクションマネージャによって保持され、後に関連のカートリッジにデータベースのハンドルを与えて、複数リクエストのトランザクションの処理を制御するために用いられる。たとえば、リクエストされたカートリッジのタイプがＳＴＯＲＥＦＲＯＮＴタイプであれば、リソースリストはＳＥＡＲＳおよびＢＡＮＫ１データベースと関連づけられる。リソースリスト情報を用いて、トランザクションマネージャは、ＳＥＡＲＳおよびＢＡＮＫ１データベースと関連づけられるデータベースサーバとのコネクションをそれぞれ確立することによって、ＳＥＡＲＳデータベースおよび／ＢＡＮＫ１データベースとのコネクションを開く。これらのコネクションはトランザクションマネージャによって保持され、ＴＸ１タイプのトランザクションを処理するために用いられる。
【０１４３】
トランザクションマネージャが（適切なデータベースと関連するデータベースサーバを通じて）適切なデータベースとそのコネクションを確立した後、カートリッジ実行エンジンは、カートリッジインスタンスに対するポインタをカートリッジファクトリに戻すことにより、カートリッジインスタンスが生成されたことをカートリッジファクトリに知らせる。カートリッジインスタンスポインタを受取ると、カートリッジファクトリはこのカートリッジインスタンスポインタをリソースマネージャへ送る。
【０１４４】
リソースマネージャはその後、カートリッジインスタンスポインタをそのカートリッジインスタンスポインタテーブルに登録する。リソースマネージャは次いで、カートリッジインスタンスポインタをディスパッチャに送る。リソースマネージャからカートリッジインスタンスポインタを受取ると、ディスパッチャはカートリッジインスタンスポインタをそれに関連するカートリッジインスタンスポインタリストに蔵置する。ディスパッチャはその後、カートリッジインスタンスポインタを用いて、変更されたブラウザリクエストをカートリッジインスタンスに送る。
【０１４５】
変更されたブラウザリクエストの作成
カートリッジインスタンスポインタを獲得すると、ディスパッチャはブラウザリクエストに関連する情報を用いて変更されたブラウザリクエストを作成する。この変更されたブラウザリクエストは、ＵＲＩ、ヘッダ情報、カートリッジのタイプ、およびメッセージをディスパッチャに戻せるようにするディスパッチャポインタを含む。たとえば、上述のＴＸ１タイプのトランザクションに対する変更されたリクエストは、次の情報を含み得る。
【０１４６】
URI = /storefront/open＿session
header = NULL
cartridge name =［STOREFRONT］
dispatcher pointer = address XXXXX
この例では、ＵＲＩは開始トランザクションＵＲＩ（複数リクエストトランザクションの開始を識別するためにカートリッジ実行エンジンによって用いられるＵＲＩ）である。このＵＲＩは開始トランザクションＵＲＩであるので、グローバルに一意のトランザクションＩＤが、複数リクエストトランザクションと関連づけられているわけではない。よって、トランザクションＩＤを含む筈であるヘッダはＮＵＬＬにセットされる。進行中の（すなわちブラウザリクエストが／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ  ｓｅｓｓｉｏｎのＵＲＩを含まないとき）、またそこでグローバルに一意のトランザクションＩＤを蔵置するためにクッキーを用いる複数リクエストのトランザクションに関して、ヘッダは一意のトランザクションＩＤを含むであろう。この一意のトランザクションＩＤにより、データベースサーバはトランザクションリクエストを進行中の複数リクエストトランザクションと関連づけることができるようになる。
【０１４７】
カートリッジ名はカートリッジのタイプを特定し、特定のブラウザリクエストと関連づけられたトランザクションのタイプについての情報を含むメタデータを特定するためにカートリッジ実行エンジンによって用いられる。この例では、ＳＴＯＲＥＦＲＯＮＴのカートリッジ名はＴＸ１に関連づけられたメタデータがブラウザリクエストに関連づけられているとして識別する。
【０１４８】
変更されたブラウザリクエストの作成後、ディスパッチャは前に獲得されたカートリッジのインスタンスポインタを用いて変更されたブラウザリクエストをカートリッジのインスタンスに送る。カートリッジのインスタンスが変更されたブラウザリクエストを受取ると、カートリッジのインスタンスはカートリッジタイプの情報を用いてブラウザリクエストと関連づけられているメタデータを識別する。メタデータの識別後、カートリッジ実行エンジンはＵＲＩ情報を用いてブラウザリクエストに関連づけられたトランザクションのステートを判定する。
【０１４９】
たとえば、ブラウザリクエストが「／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ  ｓｅｓｓｉｏｎ」というＵＲＩおよびＳＴＯＲＥＦＲＯＮＴというカートリッジタイプを含むと仮定する。
【０１５０】
カートリッジタイプＳＴＯＲＥＦＲＯＮＴと関連づけられたメタデータ（すなわち上記のＴＸ１に記載されるメタデータ）を見ることにより、カートリッジ実行エンジン２２８は／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ＿ｓｅｓｓｉｏｎというＵＲＩが「開始」トランザクションステートに対応することを決定する。この同じ機構を用いて、カートリッジ実行エンジン２２８は、／ｓｔｏｒｅｆｒｏｎｔ／ｃｏｍｍｉｔ＿ｓｅｓｓｉｏｎというＵＲＩを含むブラウザリクエストが「コミット」トランザクションステートに対応し、また／ｓｔｏｒｅｆｒｏｎｔ／ｒｏｌｌｂａｃｋ＿ｓｅｓｓｉｏｎというＵＲＩを含むブラウザリクエストが「ロールバック」トランザクションステートに対応するということを決定し得る。
【０１５１】
ＵＲＩが特定のステートを含まない（すなわちＵＲＩが／ｓｔｏｒｅｆｒｏｎｔのみから成る）場合、カートリッジ実行エンジン２２８は、ブラウザリクエストがコミットまたはロールバックのいずれの準備もできていない進行中の複数リクエストトランザクションと関連づけられていると想定する。
【０１５２】
カートリッジ実行エンジンが「開始」トランザクションと関連づけられていない変更されたブラウザリクエストを受取ると、カートリッジ実行エンジンはヘッダをチェックしてそれがグローバルに一意のトランザクションＩＤを特定しているか否かを判定する。ヘッダがグローバルに一意のトランザクションＩＤを特定していれば、グローバルに一意のトランザクションＩＤを蔵置するためにクッキー情報が用いられた。ヘッダがグローバルに一意のトランザクションＩＤを特定していなければ、カートリッジ実行エンジンはＵＲＩをサーチし、ブラウザリクエストと関連づけられるグローバルに一意のトランザクションＩＤを識別する。カートリッジ実行エンジンがグローバルに一意のトランザクションＩＤを見出すと、カートリッジ実行エンジンはトランザクションマネージャに送られるトランザクション制御メッセージ中にトランザクションＩＤを含ませる。トランザクションマネージャは関連するデータベースサーバとの通信においてグローバルに一意のトランザクションＩＤを使用し、複数リクエストトランザクションが作業のアトミック単位としてコミットされるかまたはロールバックされるかのいずれかになるようにする。
【０１５３】
トランザクションの処理
図７Ａから７Ｉは、本発明の一実施例に従ってステートレスな環境において複数リクエストトランザクションを処理するための方法を表わすフロー図である。
【０１５４】
ステップ７０２で、カートリッジ２３０に向けられた変更されたブラウザリクエストはカートリッジ実行エンジン２２８によって代行受信される。説明の目的で、変更されたブラウザリクエストはディスパッチャ２１４によって送られたと仮定され、変更されたブラウザリクエストが上記のトランザクションＴＸ１と関連づけられていると仮定する。
【０１５５】
ステップ７０４で、カートリッジ実行エンジン２２８は変更されたブラウザリクエストがトランザクションと関連づけられているか否かを判定する。変更されたブラウザリクエストがトランザクションと関連づけられていない場合、ステップ７０６で、カートリッジ実行エンジン２２８が変更されたブラウザリクエストをカートリッジ２３０に送り、カートリッジ２３０が変更されたブラウザリクエストと関連づけられるリクエストされた非トランザクション機能を実行するようにする。カートリッジはリクエストされた非トランザクション機能を一旦実行すると、カートリッジ実行エンジン２２８が次の変更されたブラウザリクエストを代行受信できるように、制御はステップ７０２へ戻る。
【０１５６】
そうでなく、変更されたブラウザリクエストがトランザクションと関連づけられている場合、ステップ７０８で、カートリッジ実行エンジン２２８はまず、変更されたブラウザリクエストが開始トランザクションＵＲＩと関連づけられているか否かを判定することにより、トランザクションのステートを決定する。変更されたブラウザリクエストが開始トランザクションＵＲＩと関連づけられているか否かを判定する際に、カートリッジ実行エンジン２２８は、カートリッジ名を用いて変更されたブラウザリクエスト中で特定されたトランザクションタイプのトランザクションの属性を含む、前に蔵置されていたメタデータを特定する。前に蔵置されたメタデータを用いて、カートリッジ実行エンジン２２８は変更されたブラウザリクエストが開始トランザクションＵＲＩと関連づけられているか否かを判定する。
【０１５７】
たとえば、変更されたブラウザリクエストが、ＳＴＯＲＥＦＲＯＮＴというカートリッジ名および／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ＿ｓｅｓｓｉｏｎというＵＲＩを含んでいたと仮定する。ＳＴＯＲＥＦＲＯＮＴというカートリッジ名を用いて、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストがトランザクションＴＸ１についてのメタデータと関連づけられていると判定する。このメタデータを用いて、カートリッジ実行エンジン２２８は、／ｓｔｏｒｅｆｒｏｎｔ／ｏｐｅｎ＿ｓｅｓｓｉｏｎというＵＲＩが開始トランザクションと関連づけられていることを決定する。
【０１５８】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストが開始トランザクションと関連づけられていないと判定すると、制御はステップ７４４に進む。
【０１５９】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストが開始トランザクションと関連づけられていると判定すれば、ステップ７１２で、カートリッジ実行エンジン２２８はトランザクション制御メッセージ中に開始トランザクション識別子（ｔｘ＿ｂｅｇｉｎ）を含ませる。カートリッジ実行エンジン２２８はその後、トランザクション制御メッセージをトランザクションマネージャ６０６に送る。
【０１６０】
ステップ７１４で、開始トランザクション識別子を受取ると、トランザクションマネージャ６０６はこの複数リクエストトランザクションに関連づけられている後続のブラウザリクエストを識別するために用いられる、グローバルに一意のトランザクションＩＤを作成する。本発明の特定の実施例では、トランザクションＩＤはブラウザＩＰアドレス、トランザクション名および特定のタイムスタンプ値を用いて形成される。
【０１６１】
ステップ７１６で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエスト中に含まれる情報から形成されたオペレーションメッセージをカートリッジ２３０に送る。このオペレーションメッセージはまた、変更されたブラウザリクエストを送ったディスパッチャ（ディスパッチャ２１４）を特定するディスパッチャポインタも含む。このポインタにより、カートリッジ２３０はディスパッチャに再び情報を書くことができるようになる。ステップ７１８で、オペレーションメッセージを受取ると、カートリッジ２３０はトランザクションマネージャ６０６にメッセージを送り、トランザクションと関連づけられているデータベースにアクセスするためのハンドルをリクエストする。
【０１６２】
ステップ７２０で、トランザクションマネージャ６０６は、カートリッジ２３０がトランザクションリクエストを処理できるようにするために、ハンドルを適切なデータベースサーバに戻す。たとえば、データベース６１０がＳＥＡＲＳデータベースと関連づけられ、データベース６１４がＢＡＮＫ１データベースと関連づけられていると仮定すれば、トランザクションマネージャ６０６はデータベースサーバ６０８および６１２にそれぞれハンドルを戻すであろう。
【０１６３】
ステップ７２２で、カートリッジ２３０はトランザクションマネージャ６０６から戻されたハンドルを用いてカートリッジ実行エンジン２２８によって送られたオペレーションメッセージ中で特定されたオペレーションを実行する。
【０１６４】
ステップ７２４で、カートリッジ２３０は、送信ブラウザがクッキー情報をブラウザに関連づけるか否かを判定する。ブラウザがブラウザにクッキー情報を関連づけさせれば、ステップ７２６で、カートリッジ２３０は、このトランザクションリクエストの実行に応答して生成されたＨＴＭＬページのハイパーリンクがグローバルに一意のトランザクションＩＤを含むようにする。ＨＴＭＬページのハイパーリンクに注釈をつけることにより、後続のブラウザリクエストに含まれるＵＲＩはグローバルに一意のトランザクションＩＤを含むであろう。
【０１６５】
ステップ７２８で、カートリッジ２３０はディスパッチャポインタを用いて、トランザクションリクエストの実行に応答して生成されたＨＴＭＬページをディスパッチャ２１４に戻す。カートリッジ２３０はその後、カートリッジ実行エンジン２２８に、トランザクションリクエストの実行が完了したことを知らせる。
【０１６６】
ステップ７３０で、カートリッジ実行エンジン２２８はトランザクションマネージャ６０６にメッセージを送り、トランザクションをサスペンドするようにリクエストする。ステップ７３２で、トランザクションマネージャ６０６はサスペンドリクエストをデータベースサーバ６０８および６１２に送り、それらにトランザクションの実行をサスペンドさせる。サスペンドリクエストはグローバルに一意のトランザクションＩＤを含むので、データベースサーバ６０８および６１２はどのトランザクションをサスペンドすべきかを知る。データベースサーバ６０８および６１２にサスペンドリクエストを送ることにより、他のブラウザもデータベース６１０および６１４に関連づけられているトランザクションを実行できるようになる。
【０１６７】
ステップ７３４で、トランザクションマネージャ６０６はカートリッジ実行エンジン２２８にグローバルに一意のトランザクションＩＤを送る。ステップ７３６で、カートリッジ実行エンジン２２８は送信ブラウザがクッキー情報をブラウザに関連づけているか否かを判定する。ブラウザがクッキー情報をブラウザに関連づけていない場合、ステップ７３８で、ディスパッチャ２１４は変更されたブラウザリクエストの処理が完了したことを知らされる。その後、制御はステップ７０２に戻り、別の変更されたブラウザリクエストを代行受信する。
【０１６８】
ブラウザが、クッキー情報をそのブラウザに関連づけると、ステップ７４０で、カートリッジ実行エンジン２２８はグローバルに一意のトランザクションＩＤを用いて、送信ブラウザと関連づけられるようにクッキー情報を作成する。
【０１６９】
ステップ７４２で、カートリッジ実行エンジン２２８はクッキー情報をディスパッチャ２１４に送るので、それは送信ブラウザに伝送され、変更されたブラウザリクエストの処理が完了したことをディスパッチャ２１４に知らせることができる。その後、制御はステップ７０２に戻り、別の変更されたブラウザリクエストを代行受信する.
ステップ７４４で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストがコミットトランザクションＵＲＬと関連づけられているか否かを判定する。変更されたブラウザリクエストがコミットトランザクションＵＲＩと関連づけられているか否かを判定する際に、カートリッジ実行エンジン２２８はカートリッジ名を用いて、変更されたブラウザリクエストに関連するトランザクションのタイプについて前に蔵置されたメタデータを特定する。前に蔵置されたメタデータを用いて、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストがコミットトランザクションＵＲＩと関連づけられているか否かを判定する。
【０１７０】
たとえば、変更されたブラウザリクエストがＳＴＯＲＥＦＲＯＮＴというカートリッジ名および／ｓｔｏｒｅｆｒｏｎｔ／ｃｏｍｍｉｔ＿ｓｅｓｓｉｏｎというＵＲＩを含むと仮定する。このＳＴＯＲＥＦＲＯＮＴというカートリッジ名を用いて、カートリッジ実行エンジン２２８は変更されたブラウザリクエストがトランザクションＴＸ１についてのメタデータと関連づけられていると判定する。このメタデータを用いて、カートリッジ実行エンジン２２８は、／ｓｔｏｒｅｆｒｏｎｔ／ｃｏｍｍｉｔ＿ｓｅｓｓｉｏｎというＵＲＩがコミットトランザクションと関連づけられていると判定する。
【０１７１】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストがコミットトランザクションと関連づけられていないと判定した場合、制御はステップ７７４へと進む。
【０１７２】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストがコミットトランザクションに関連づけられていると判定した場合、ステップ７４６で、カートリッジ実行エンジン２２８は変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むか否かを判定する。カートリッジ実行エンジン２２８が、変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むと判定すれば、ステップ７４８でカートリッジ実行エンジン２２８はそのクッキー情報からグローバルに一意のトランザクションＩＤを抽出する。そして制御はステップ７５２へと進む。
【０１７３】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストのヘッダ部分がクッキー情報を含まないと判定した場合、ステップ７５０でカートリッジ実行エンジン２２８は注釈付きＵＲＬからグローバルに一意のトランザクションＩＤを抽出する。
【０１７４】
ステップ７５２で、カートリッジ実行エンジン２２８は再開トランザクション識別子（ｔｘ＿ｒｅｓｕｍｅ）をトランザクション制御メッセージ中にパックする。カートリッジ実行エンジン２２８はその後トランザクション制御メッセージをトランザクションマネージャ６０６に送る。
【０１７５】
ステップ７５４で、再開トランザクション識別子を受取ると、トランザクションマネージャ６０６は再開リクエストをデータベースサーバ６０８および６１２に送り、それらにトランザクションの実行を再開させる。再開リクエストは、データベースサーバ６０８および６１２が現在のトランザクションリクエストと関連づけられている複数リクエストトランザクションを識別できるようにするグローバルに一意のトランザクションＩＤを含む。
【０１７６】
ステップ７５６で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストに含まれるトランザクション情報に基づくオペレーションメッセージをカートリッジ２３０に送る。このオペレーションメッセージはまた、変更されたブラウザリクエストを送ったディスパッチャ（ディスパッチャ２１４）を特定し、かつカートリッジ２３０がディスパッチャに情報を再び書き込むことができるようにする、ディスパッチャポインタも含む。ステップ７５８で、オペレーションメッセージを受取ると、カートリッジ２３０は、トランザクションと関連づけられるデータベースにアクセスするためのハンドルをリクエストするメッセージをトランザクションマネージャ６０６に送る。
【０１７７】
ステップ７６０で、トランザクションマネージャ６０６はハンドルを適切なデータベースサーバに戻し、カートリッジ２３０がトランザクションリクエストを処理できるようにする。たとえば、データベース６１０がＳＥＡＲＳデータベースに関連づけられ、データベース６１４がＢＡＮＫ１データベースに関連づけられると仮定すれば、トランザクションマネージャ６０６はデータベースサーバ６０８および６１２にそれぞれハンドルを戻すであろう。
【０１７８】
ステップ７６２で、カートリッジ２３０はトランザクションマネージャ６０６から戻されたハンドルを用いて、カートリッジ実行エンジン２２８によって送られたオペレーションメッセージにより特定されたオペレーションを実行する。
【０１７９】
ステップ７６４で、カートリッジ２３０は、送信ブラウザがクッキー情報をブラウザに関連づけるのを許容するか否かを判定する。ブラウザがクッキー情報をブラウザに関連づけさせない場合、ステップ７６６で、カートリッジ２３０は、トランザクションと関連づけられたＨＴＭＬページすべての注釈付きハイパーリンクからグローバルに一意のトランザクションＩＤを取除く。ＨＴＭＬページのハイパーリンクからトランザクションＩＤの注釈を取除くことにより、ＨＴＭＬページからのハイパーリンクの選択に応答して発行される後続のブラウザリクエストはグローバルに一意のトランザクションＩＤを含まないことになり、したがって、この複数リクエストトランザクションと誤って関連づけられることはないであろう。
【０１８０】
ステップ７６８で、カートリッジ２３０はディスパッチャポインタを用いて、ディスパッチャ２１４へのブラウザリクエストにおいて特定されたオペレーションの実行に応答して生成されたＨＴＭＬページを戻し、カートリッジ実行エンジン２２８にトランザクションリクエストの実行が完了したことを知らせる。
【０１８１】
ステップ７７０で、カートリッジ実行エンジン２２８はトランザクション制御メッセージをトランザクションマネージャ６０６に送り、それにトランザクションをコミットするようにリクエストする。ステップ７７１で、トランザクションマネージャ６０６はコミットリクエストをデータベースサーバ６０８および６１２に送り、複数リクエストトランザクションに所属するさまざまなブラウザリクエストに応答してなされたすべての変更を、作業のアトミック単位としてコミットさせる。このコミットリクエストは、データベースサーバ６０８および６１２が関連の複数リクエストトランザクションを識別できるようにするグローバルに一意のトランザクションＩＤを含む。
【０１８２】
ステップ７７２で、カートリッジ実行エンジン２２８はディスパッチャ２１４に、変更されたブラウザリクエストの処理が完了したことを知らせ、またディスパッチャ２１４に、コミットされた複数リクエストトランザクションに関連づけられたクッキー情報を送信ブラウザから取除くように知らせる。送信ブラウザに関連づけられたクッキー情報からトランザクションＩＤを取除くことにより、後続のブラウザリクエストはグローバルに一意のトランザクションＩＤを含まないことになり、したがって、コミットされた複数リクエストトランザクションと誤って関連づけられることもないであろう。この後制御はステップ７０２へ戻り、別の変更されたブラウザリクエストを代行受信する。
【０１８３】
ステップ７７４で、カートリッジ実行エンジン２２８は変更されたブラウザリクエストがロールバックトランザクションＵＲＩと関連づけられているか否かを判定する。変更されたブラウザリクエストがロールバックトランザクションＵＲＩと関連づけられているか否かを判定する際に、カートリッジ実行エンジン２２８は、カートリッジ名を用いて、変更されたブラウザリクエスト中で示されたトランザクションのタイプに対応する、前に蔵置されたメタデータを識別する。前に蔵置されたメタデータを用いて、カートリッジ実行エンジン２２８は変更されたブラウザリクエストがロールバックトランザクションＵＲＩを含むか否かを判定する。
【０１８４】
たとえば、変更されたブラウザリクエストはＳＴＯＲＥＦＲＯＮＴというカートリッジ名、および／ｓｔｏｒｅｆｒｏｎｔ／ｒｏｌｌｂａｃｋ＿ｓｅｓｓｉｏｎというＵＲＩを含むと仮定される。ＳＴＯＲＥＦＲＯＮＴというカートリッジ名を用いて、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストがトランザクションＴＸ１についてのメタデータに関連づけられていると判定する。このメタデータを用いて、カートリッジ実行エンジン２２８は／ｓｔｏｒｅｆｒｏｎｔ／ｒｏｌｌｂａｃｋ＿ｓｅｓｓｉｏｎというＵＲＩがロールバックトランザクションに関連づけられていると判定する。
【０１８５】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストがロールバックトランザクションと関連づけられていないと判定すれば、制御はステップ８０４に進む。
【０１８６】
カートリッジ実行エンジン２２８が、変更されたブラウザリクエストがロールバックトランザクションと関連づけられていると判定すれば、ステップ７７６で、カートリッジ実行エンジン２２８は変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むか否かを判定する。変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むとカートリッジ実行エンジン２２８が判定すれば、ステップ７７８で、カートリッジ実行エンジン２２８はそのクッキー情報からグローバルに一意のトランザクションＩＤを抽出する。その後制御は７８２へ進む。
【０１８７】
変更されたブラウザリクエストのヘッダ部分がクッキー情報を含まないとカートリッジ実行エンジン２２８が判定すれば、ステップ７８０で、カートリッジ実行エンジン２２８は注釈付きＵＲＩからグローバルに一意のトランザクションＩＤを抽出する。
【０１８８】
ステップ７８２で、カートリッジ実行エンジン２２８は、再開トランザクション識別子（ｔｘ＿ｒｅｓｕｍｅ）をトランザクション制御メッセージに組込む。カートリッジ実行エンジン２２８はその後、トランザクション制御メッセージをトランザクションマネージャ６０６に送る。
【０１８９】
ステップ７８４で、再開トランザクション識別子を受取ると、トランザクションマネージャ６０６は再開リクエストをデータベースサーバ６０８および６１２に送り、それらにトランザクションの実行を再開させる。この再開リクエストは、データベースサーバ６０８および６１２が現在のトランザクションリクエストと関連づけられている複数リクエストトランザクションを識別できるようにするグローバルに一意のトランザクションＩＤを含む。
【０１９０】
ステップ７８６で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストに含まれるトランザクション情報に基づくオペレーションメッセージをカートリッジ２３０に送る。このオペレーションメッセージはまた、変更されたブラウザリクエストを送ったディスパッチャ（ディスパッチャ２１４）を特定してカートリッジ２３０が情報を再びディスパッチャに書込めるようにする、ディスパッチャポインタも含む。ステップ７８８で、オペレーションメッセージを受取ると、カートリッジ２３０はメッセージをトランザクションマネージャ６０６に送り、特定のタイプのトランザクションにおいて用いられるデータベースにアクセスするためのハンドルをリクエストする。
【０１９１】
ステップ７９０で、トランザクションマネージャ６０６は適切なデータベースサーバにハンドルを戻し、カートリッジ２３０がトランザクションリクエストを処理できるようにする。たとえば、データベース６１０はＳＥＡＲＳデータベースと関連づけられ、データベース６１４はＢＡＮＫ１データベースと関連づけられていると仮定すれば、トランザクションマネージャ６０６はそれぞれデータベースサーバ６０８および６１２にハンドルを戻すであろう。
【０１９２】
ステップ７９２で、カートリッジ２３０はトランザクションマネージャ６０６から戻されたハンドルを用いて、カートリッジ実行エンジン２２８によって送られたオペレーションメッセージに関連づけられているトランザクション情報を実行する。
【０１９３】
ステップ７９４で、カートリッジ２３０は、送信ブラウザがクッキー情報をブラウザに関連づけるのを許容するか否かを判定する。ブラウザがクッキー情報をブラウザに関連づけさせない場合、ステップ７９６で、カートリッジ２３０は、ＨＴＭＬページすべての注釈付きハイパーリンクからグローバルに一意のトランザクションＩＤを取除き、ブラウザに戻す。トランザクションＩＤの注釈をＨＴＭＬページのハイパーリンクから取除くことにより、後続のブラウザリクエストがグローバルに一意のトランザクションＩＤを含むことはなくなり、したがってこの複数リクエストトランザクションと誤って関連づけられることもないであろう。
【０１９４】
ステップ７９８で、カートリッジ２３０は、ディスパッチャポインタを用いて、トランザクションの実行と関連づけられたＨＴＭＬページをディスパッチャ２１４に戻し、カートリッジ実行エンジン２２８にトランザクションリクエストの実行が完了したことを知らせる。
【０１９５】
ステップ８００で、カートリッジ実行エンジン２２８はトランザクション制御メッセージをトランザクションマネージャ６０６に送り、それにトランザクションのロールバックをリクエストする。ステップ８０１で、トランザクションマネージャ６０６はロールバックリクエストをデータベースサーバ６０８および６１２に送り、複数リクエストトランザクションに所属するブラウザリクエストに応答してなされたすべての変更を、作業のアトミック単位としてロールバックさせる。ロールバックリクエストは、データベースサーバ６０８および６１２が正しい複数リクエストトランザクションを特定しかつロールバックできるようにする、グローバルに一意のトランザクションＩＤを含む。
【０１９６】
ステップ８０２で、カートリッジ実行エンジン２２８はディスパッチャ２１４に、変更されたブラウザリクエストの処理が完了したことを知らせ、またディスパッチャ２１４にロールバック複数リクエストトランザクションに関連づけられるクッキー情報を送信ブラウザから取除くように知らせる。トランザクションＩＤを送信ブラウザに関連づけられるクッキー情報から取除くことにより、後続のブラウザリクエストはグローバルに一意のトランザクションＩＤを含まなくなり、したがってロールバックされた複数リクエストトランザクションと誤って関連づけられることもないであろう。この後、制御はステップ７０２へ戻り、別の変更されたブラウザリクエストを代行受信する。
【０１９７】
ステップ８０４で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むか否かを判定する。変更されたブラウザリクエストのヘッダ部分がクッキー情報を含むとカートリッジ実行エンジン２２８が判定した場合、ステップ８０６でカートリッジ実行エンジン２２８はクッキー情報からグローバルに一意のトランザクションＩＤを抽出する。その後、制御は８１０へ進む。
【０１９８】
変更されたブラウザリクエストがクッキー情報を含まないとカートリッジ実行エンジン２２８が判定すれば、ステップ８０８で、カートリッジ実行エンジン２２８は注釈付きＵＲＩからグローバルに一意のトランザクションＩＤを抽出する。
【０１９９】
ステップ８１０で、カートリッジ実行エンジン２２８がトランザクション制御メッセージに再開トランザクション識別子（ｔｘ＿ｒｅｓｕｍｅ）をパックする。カートリッジ実行エンジン２２８はその後、トランザクション制御メッセージをトランザクションマネージャ６０６に送る。
【０２００】
ステップ８１２で、再開トランザクション識別子を受取ると、トランザクションマネージャ６０６は再開リクエストをデータベースサーバ６０８および６１２に送り、それらにトランザクションの実行を再開させる。この再開リクエストは、データベースサーバ６０８および６１２が現在のトランザクションリクエストと関連づけられている複数リクエストトランザクションを特定できるようにする、グローバルに一意のトランザクションＩＤを含む。
【０２０１】
ステップ８１４で、カートリッジ実行エンジン２２８は、変更されたブラウザリクエストに含まれるトランザクション情報に基づくオペレーションメッセージをカートリッジ２３０に送る。オペレーションメッセージはまた、変更されたブラウザリクエストに送られたディスパッチャ（ディスパッチャ２１４）を識別してカートリッジ２３０が再びディスパッチャに情報を書込めるようにするディスパッチャポインタも含む。ステップ８１６で、オペレーションメッセージを受取ると、カートリッジ２３０はメッセージをトランザクションマネージャ６０６に送り、トランザクションに関連づけられるデータベースへのアクセスのためのハンドルをリクエストする。
【０２０２】
ステップ８１８で、トランザクションマネージャ６０６はハンドルを適切なデータベースサーバに戻し、カートリッジ２３０がトランザクションリクエストを処理できるようにする。たとえば、データベース６１０がＳＥＡＲＳデータベースと関連づけられ、データベース６１４がＢＡＮＫ１データベースと関連づけられていると仮定すると、トランザクションマネージャ６０６はハンドルをそれぞれデータベースサーバ６０８および６１２に戻すであろう。
【０２０３】
ステップ８２０で、カートリッジ２３０はトランザクションマネージャ６０６から戻されたハンドルを用いて、カートリッジ実行エンジン２２８によって送られたオペレーションメッセージ中で特定されたオペレーションを実行する。
【０２０４】
ステップ８２２で、カートリッジ２３０は、送信ブラウザがクッキー情報をブラウザと関連づけるのを許容するか否かを判定する。ブラウザがクッキー情報をブラウザと関連づけさせなければ、ステップ８２４で、カートリッジ２３０は、オペレーションの実行に応答して生成されるＨＴＭＬページのハイパーリンクに注釈をつけてグローバルに一意のトランザクションＩＤを含むようにする。ＨＴＭＬページのハイパーリンクに注釈をつけることにより、ＨＴＭＬページにおけるリンクの選択に応答して発行される後続のブラウザリクエストのＵＲＩは、グローバルに一意のトランザクションＩＤを含むであろう。
【０２０５】
ステップ８２６で、カートリッジ２３０は、ディスパッチャポインタを用いてこのようにして生成されたＨＴＭＬページをディスパッチャ２１４に戻し、カートリッジ実行エンジン２２８に、トランザクションリクエストの実行が完了したことを知らせる。
【０２０６】
ステップ８２８で、カートリッジ実行エンジン２２８はメッセージをトランザクションマネージャ６０６に送り、トランザクションをサスペンドするようにリクエストする。ステップ８３０で、トランザクションマネージャ６０６はデータベースサーバ６０８および６１２にサスペンドリクエストを送り、それらにトランザクションの実行をサスペンドさせる。このサスペンドリクエストは、データベースサーバ６０８および６１２が、サスペンドされるべき複数リクエストトランザクションを正確に特定できるようにする、グローバルに一意のトランザクションＩＤを含む。この後、制御はステップ７０２へ戻り、別の変更されたブラウザリクエストを代行受信する。
【０２０７】
トランザクションタイムアウト
本発明の一実施例に従って、タイムアウト値は各トランザクションと関連づけられる。タイムアウト値は、特定された時間アクティブにされていなかった複数リクエストのトランザクションを識別するために用いられる。一実施例では、各データベースサーバは、そのデータベースサーバによってサービスを受けている複数リクエストトランザクションについてのタイムアウト値を維持する。したがって、複数リクエストトランザクションが実行を開始すると常に、関連のデータベースサーバは特定のトランザクションについてのタイムアウト値を初期化する。グローバルに一意のトランザクションＩＤに関連づけられる再開トランザクションリクエストを受取ると、データベースサーバはグローバルに一意のトランザクションＩＤに関連づけられる複数リクエストトランザクションについてのタイムアウト値をリセットする。複数リクエストトランザクションがタイムアウトすれば、データベースサーバは複数リクエストトランザクションの一部としてなされたすべての変更を作業のアトミック単位としてロールバックさせる。複数リクエストトランザクションが一旦ロールバックされると、メッセージは関連のブラウザへ送られ、トランザクションのステートを示す。
【０２０８】
ステートレスなウェブ環境におけるトランザクションの実行
本発明は、ウェブなどのステートレスな環境において複数リクエストトランザクションを実行するための実用的かつ高度にスケーラブルな機構を提供する。本発明に従えば、トランザクションマネージャは全トランザクション処理を調整するために用いられる。好ましくは、トランザクションマネージャは、ステート情報がトランザクションマネージャ自体がステート情報を持続的に維持する必要なく、トランザクションについて維持されるように、処理を調整する。
【０２０９】
好ましい実施例では、クライアントリクエストの処理は次のとおり実行される。トランザクションマネージャはクライアントからリクエストを受取り、そのリクエストがトランザクションリクエストであれば、データベース管理システム（ＤＢＭＳ）などのトランザクション処理機構でトランザクションを開始する。一旦、トランザクションが開始されると、マネージャは好ましくはそのリクエストをアプリケーションなどの別のエンティティに送り、これが実際にリクエストを処理する。リクエストの処理後、制御はマネージャへ戻り、その時点で、マネージャはトランザクションに関連づけられた１組のステート情報を集める。このステート情報は、クライアントのアイデンティティ、トランザクションのステータス、ならびにトランザクション中で既に明らかになっているものを含み得る。一旦集められると、ステート情報は、クライアントリクエストに対する応答とともに、クライアントに再び送られ、クライアントによって維持される。ステート情報は、「クッキー」の形態でクライアントに送られてもよく、またはクライアントに戻されるＵＲＬに組込まれてもよい。そうすることが可能であるのに対して、ステート情報はマネージャまたはリクエストを処理したアプリケーションによって持続的に維持されないことが好ましい。
【０２１０】
クライアントが同じトランザクションに関する第２のリクエストを出すとき、そのクライアントはマネージャによって前に与えられたステート情報とともに送る。第２のリクエストを受取ると、マネージャはそのリクエストからステート情報を抽出し、それを用いて、ＤＢＭＳで前に開始されたトランザクションを再開する。トランザクションが一旦再開されると、マネージャはステート情報を含む第２のリクエストを別のエンティティ（同じまたは異なるアプリケーション）に送り、処理する。第２のリクエストの処理後、マネージャはトランザクションに関連づけられたステート情報を更新し、その更新したステート情報を第２のリクエストに対する応答とともにクライアントへ送る。クライアントは将来のリクエストにおいてこの更新されたステート情報を送り、トランザクションを再開するであろう。このプロセスはトランザクションがコミットされるかまたはロールバックされるまで繰返される。
【０２１１】
本発明はいくつかの重要な利点を提供する。第１に、リクエストを処理するトランザクションマネージャおよびアプリケーションはステートレスのままであることに注目されたい。すなわち、トランザクションマネージャおよびアプリケーションは、トランザクションに対していかなるステート情報も維持する必要がない。その情報はすべてクライアントによって維持される。これは、情報を蔵置するためのオーバーヘッドが全く生じないということを意味する。より重要なことに、クライアントがそれ自体のステート情報を維持するという事実は、クライアントからのいかなるリクエストでも何らかのスレッド、プロセス、またはノードによって処理できるということを意味する。これにより、各クライアントに対して専用のプロセスまたはスレッドを有する必要がなくなるので、スケーラビリティは著しく向上する。
【０２１２】
別の留意すべき点は、クライアントがステート情報を維持しているとしても、クライアントはトランザクション特有のステート情報を維持していることに気づかないという点である。上述したように、ステート情報はトランザクションマネージャによってクライアントに与えられる。クライアントは単に、それが次のリクエストを出すときにこの情報をトランザクションマネージャに戻す。クライアントは、それがステート情報を維持していることを意識していないし、また意識する必要もない。これは本発明の非常に有利な局面である。なぜなら、このことにより、クライアントに何らかのステート管理論理を課す必要が回避できるからである。これはまた、本発明を適切に実行するために、クライアントに対していかなる変更または追加をする必要もないということを意味する。
【０２１３】
したがって、本発明は、ステートレスな環境においてトランザクションを実行するための実用的、スケーラブル、かつ効果的な機構を提供する。本発明のこれらおよび他の利点は、本発明をさらに詳細に述べることにより明らかになるであろう。
【０２１４】
ＵＲＬＳへのステート情報の組込み
本発明は、ウェブなどのステートレスな環境において複数リクエストオペレーション（トランザクションを含むがそれに限定されない）をサポートするための、効果的かつ高度にスケーラブルな機構を提供する。本発明に従って、クライアントリクエストの全処理を調整するために、好ましくはサーバが用いられる。好ましくは、このサーバは、（１）複数リクエストオペレーションと関連づけられるステート情報がリクエストを出すクライアントによって維持され、（２）クライアントがそれらがオペレーション特有のステート情報を維持していることに気づかず、さらに（３）サーバ自体はステート情報を持続的に維持する必要がないのでステートレスのままであるように、この調整機能を実行する。
【０２１５】
好ましい実施例では、クライアントリクエストの処理は次のように行なわれる。サーバがクライアントからのリクエストを受取り、そのリクエストが複数リクエストオペレーションについてのものであれば、サーバはオペレーションを開始する。オペレーションが一旦開始されると、サーバは、リクエストを処理するために別々のエンティティ（アプリケーションなど）に送るか、またはサーバがそのリクエストをそれ自体で処理するかのいずれかであり得る。リクエストの処理後、サーバはオペレーションに関連づけられる１組のステート情報を集める。このステート情報は、クライアントのアイデンティティ、オペレーションのＩＤおよびステータス、オペレーションにおいて既に明らかになっているもの、およびオペレーションに関連づけられる他の何らかのコンテキスト情報を含み得る。一旦集められると、ステート情報はＵＲＬに組込まれる。このＵＲＬは、クライアントリクエストに対する応答とともに、再びクライアントに送られ、クライアントによって維持される。このステート情報は、サーバによって持続的に維持されないことが好ましい。
【０２１６】
クライアントが同じオペレーションに関する第２のリクエストを出すと、クライアントはステート情報を含むサーバによって前に与えられたＵＲＬを送る。第２のリクエストを受取ると、サーバはＵＲＬからステート情報を抽出し、それを用いて前に開始されたオペレーションを再開する。このステート情報のおかげで、サーバは前のリクエストが止まったまさにその点でオペレーションを再開することができる。オペレーションが一旦再開されると、サーバはリクエストを処理するか、またはそれを別のエンティティへ送ってから処理させる。第２のリクエストの処理後、サーバはオペレーションに関連づけられるステート情報を更新し、その更新したステート情報を別のＵＲＬに組込む。このＵＲＬは、第２のリクエストに対する応答とともに、再びクライアントに送られてクライアントによって維持される。クライアントは将来のリクエストの際に、このＵＲＬを送ってオペレーションを再開させるであろう。このプロセスはオペレーションが完了するかまたはキャンセルされるかのいずれかまで、繰返される。
【０２１７】
本発明はいくつかの重要な利点を提供する。まず、サーバがステートレスのままであることに留意されたい。すなわち、サーバはトランザクションに対していかなるステート情報も維持する必要がない。その情報はすべてクライアントによって維持される。これは、情報の蔵置のためのオーバーヘッドが全く生じないということを意味する。より重要なことには、クライアントがそれ自体のステート情報を維持するという事実は、クライアントからのいかなるリクエストも、何らかのスレッド、プロセス、またはノードによって処理できるということを意味する。これにより、各クライアントに対して専用のプロセスまたはスレッドを有する必要がなくなるので、スケーラビリティは著しく向上する。
【０２１８】
別の留意すべき点は、クライアントがステート情報を維持していても、クライアントはそれがオペレーション特有のステート情報を維持していることを意識していないという点である。上述したように、ステート情報はＵＲＬの形式でサーバからクライアントに与えられる。クライアントはそれがサーバからのサービスをリクエストするたびにこのＵＲＬを単に送るだけである。クライアントはこのＵＲＬを他のすべてのＵＲＬと同様に扱う。クライアントは、このＵＲＬがステート情報を含んでいることを意識していないし、意識する必要もない。これは本発明の非常に有利な局面である。なぜなら、これによりクライアントに何らかのステート管理論理を課す必要が回避できるからである。これはまた、本発明を適切に実行するためにクライアントに対していかなる変更または追加をなす必要もないということを意味する。
【０２１９】
したがって、本発明は、ステートレスな環境において複数リクエストのオペレーションをサポートするための実用的、スケーラブル、かつ効果的な機構を提供する。本発明のこれらおよび他の利点は本発明をさらに詳細に述べるにつれて明らかになるであろう。
【０２２０】
これまで述べてきた明細書では、本発明はその特定の実施例に関して述べられている。しかしながら、当然、本発明のより広い範囲から離れることなく、これに対してさまざまな変更および修正をなすことができる。したがって、明細書および図面は限定的なものではなく例示的なものとしてみなされるべきである。
【図面の簡単な説明】
【図１】  この発明の一実施例が実装され得るコンピュータシステムのブロック図である。
【図２】  この発明の一実施例による分散アプリケーションサーバのブロック図である。
【図３Ａ】  この発明の一実施例によるブラウザリクエストを処理するためのステップを示すフローチャートの一部の図である。
【図３Ｂ】  この発明の一実施例によるブラウザリクエストを処理するためのステップを示すフローチャートの別の部分の図である。
【図４】  この発明の一実施例によるディスパッチャが維持する情報を含む表のブロック図である。
【図５】  この発明の一実施例によるリソースマネージャが維持する情報を含む表のブロック図である。
【図６】  本発明の一実施例に従ったトランザクションの処理に対する分配されたアプリケーションのブロック図である。
【図７Ａ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の一部である。
【図７Ｂ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｃ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｄ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｅ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｆ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｇ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｈ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図７Ｉ】  本発明の一実施例に従ったステートレスな環境における複数リクエストトランザクションの処理に対するステップを表すフロー図の別の部分である。
【図１】
0004729172.tif 000004
【図２】
0004729172.tif 000005
【図３Ａ】
0004729172.tif 000006
【図３Ｂ】
0004729172.tif 000007
【図４】
0004729172.tif 000008
【図５】
0004729172.tif 000009
【図６】
0004729172.tif 000010
【図７Ａ】
0004729172.tif 000011
【図７Ｂ】
0004729172.tif 000012
【図７Ｃ】
0004729172.tif 000013
【図７Ｄ】
0004729172.tif 000014
【図７Ｅ】
0004729172.tif 000015
【図７Ｆ】
0004729172.tif 000016
【図７Ｇ】
0004729172.tif 000017
【図７Ｈ】
0004729172.tif 000018
【図７Ｉ】
0004729172.tif 000019