■お題
セッションを使うWebシステムにおいて、
同一ログイン名の人が、ログインしたらどうするか?
という問題があり、
たぶん、一般的な解答は、
「複数回ログインは、可能だが、ある一定回数がきたら、
「これ以上、ログインできません」
というエラーメッセージを出してログインさせない」
という回答がふつうではないだろうか。
(一定回数=ライセンス数)
■先勝ち方式
この場合、
・同一セッションが既に存在する場合(=一つのブラウザからタブで2回ログインしてる)
同一セッションでは、複数ログインさせないのであれば、
2回目のとき、上記エラーメッセージを出して、ログインさせない
又は
現在ログイン中の同じ画面がでる(gooはこちら)
複数ログインさせる場合
別のセッションID等を降って別セッション(相当)でログイン、
何人ログインしたかは、下記「・・・複数ログイン」の方法に従う
→別のセッションにしなければならないわけでなく、領域が分かれていれば、
同一セッション内でも、別のURL先でもよい。そういう意味で
別セッション「相当」と、「相当」の字をつけている
→これを考慮しないで、単にセッションとってきて、ログイン情報を書き込んでしまうと、
前にログインしている人の処理が消えてしまう。
→この場合、Cookieで管理すると、後の人のセッションID相当が入る可能性があるので、
それなりの注意(切り分け処理)が必要
・同一セッションではないとき、複数ログイン
どこかでユーザーログイン人数を管理。
ログイン要求が来たら、毎回新しいセッションID相当を発行し、セッションを作成
この場合、セッション終了(タイムアウトとユーザー手動の両方)の場合、
javax.servlet.http.HttpSessionBindingListenerインターフェイス
http://ash.jp/java/webapp_session.htm
(のセッションの開始・終了時の処理)
で、ユーザーログイン数を引く処理する
これは、先に入った人が必ず入れる方式なので、「先勝ち方式」と呼ぶことにする
■先勝ち方式の問題点
この方法は、たとえば、ライセンス数2のとき
・1個目のブラウザでAという処理をかけた→処理中になって、操作できない
・2個目のブラウザでBという処理をかけた→処理中になって、操作できない
Cという処理を本当はしたいんだけど・・・
2つとも処理中なので、ログインできず、処理Cを投入できない
という状態になってしまう。
特にライセンス数2でなく、ライセンス1の場合、
ある処理をやったら、処理中になっちゃって、何も操作できない・・・
処理をとめることさえ出来ない(Xボタンが利かない)
っていうのは、問題なのだ
■後勝ち方式の誕生
この問題を回避するため、
・ログイン数が一定数を超えたら、古いものから順に、セッション強制開放し、
新しい人のログインを優先させる
という手法が出てきた。ここでは後勝ち手法と呼ぶ。
このとき、強制開放された処理は、セッションが開放されているので、戻ってきたときに
異常終了する
一見、この方法で、うまくいくように思う・・・
■後勝ち方式の問題点
しかし、実は問題があるケースがある。
この「セッションを強制開放させられる」先の処理が、
ビッグデータ検索等を行っていて、すぐに帰ってこない場合。
(→だから処理中になっていて、だから、後からログインしたいわけだ)
先の処理をキャンセルしなければ、あとの処理は投入しても、
とってもおそい(たぶん、先の処理が終わってから投入したほうが早い。
だけど、先の処理の終わりを待てないから、今投入したんだ!)
このとき、1つ1つのサーブレットのインスタンスから直接、処理を
呼び出しているのなら、The Endだが、普通こういうときは、
キューにいれている。したがって、キューをキャンセルしなければならない。
このことを意識して、コーディングしている場合は問題ないが、
意識していないと、
・先の強制開放する処理のセッションを開放する
→開放されたセッションは、 HttpSessionBindingListener のvalueUnbound で
キューをキャンセルに行く
・後のログインに対するセッションを確保して、かえる
とプログラムを書いてしまう。
こう書くと、キューをキャンセルにいって、失敗したとき(あるいはなかなかキャンセル
出来なかったとき)、結局、あとでログインした人は、投入した処理は、待たされる。
■対策
制限人数(ライセンス数)を超えてログインしたら
「制限人数を超えています。先にログインした人を消しますか?」
ときいて、Noがクリックされたら、そこで終了(ログインできない)
YESがクリックされたら、
・消す人のビッグデータ検索等の処理がキュー入っていたら、それを中止する
・後処理して、セッション開放する
・これが成功したのを確認して、新しいログインに対して、セッションを発行する
→この間に失敗したり、CANCELされたら、新しいセッションが発行されず
「ふるい人のセッションも異常終了する(のを仕様とする)」
・古い人は、サーバーアクセスしたときに、異常終了通知を受け取る
とすればよい。
(後がち、先勝ちは、YES,NOのクリックでユーザーが選べる)
セッションを使うWebシステムにおいて、
同一ログイン名の人が、ログインしたらどうするか?
という問題があり、
たぶん、一般的な解答は、
「複数回ログインは、可能だが、ある一定回数がきたら、
「これ以上、ログインできません」
というエラーメッセージを出してログインさせない」
という回答がふつうではないだろうか。
(一定回数=ライセンス数)
■先勝ち方式
この場合、
・同一セッションが既に存在する場合(=一つのブラウザからタブで2回ログインしてる)
同一セッションでは、複数ログインさせないのであれば、
2回目のとき、上記エラーメッセージを出して、ログインさせない
又は
現在ログイン中の同じ画面がでる(gooはこちら)
複数ログインさせる場合
別のセッションID等を降って別セッション(相当)でログイン、
何人ログインしたかは、下記「・・・複数ログイン」の方法に従う
→別のセッションにしなければならないわけでなく、領域が分かれていれば、
同一セッション内でも、別のURL先でもよい。そういう意味で
別セッション「相当」と、「相当」の字をつけている
→これを考慮しないで、単にセッションとってきて、ログイン情報を書き込んでしまうと、
前にログインしている人の処理が消えてしまう。
→この場合、Cookieで管理すると、後の人のセッションID相当が入る可能性があるので、
それなりの注意(切り分け処理)が必要
・同一セッションではないとき、複数ログイン
どこかでユーザーログイン人数を管理。
ログイン要求が来たら、毎回新しいセッションID相当を発行し、セッションを作成
この場合、セッション終了(タイムアウトとユーザー手動の両方)の場合、
javax.servlet.http.HttpSessionBindingListenerインターフェイス
http://ash.jp/java/webapp_session.htm
(のセッションの開始・終了時の処理)
で、ユーザーログイン数を引く処理する
これは、先に入った人が必ず入れる方式なので、「先勝ち方式」と呼ぶことにする
■先勝ち方式の問題点
この方法は、たとえば、ライセンス数2のとき
・1個目のブラウザでAという処理をかけた→処理中になって、操作できない
・2個目のブラウザでBという処理をかけた→処理中になって、操作できない
Cという処理を本当はしたいんだけど・・・
2つとも処理中なので、ログインできず、処理Cを投入できない
という状態になってしまう。
特にライセンス数2でなく、ライセンス1の場合、
ある処理をやったら、処理中になっちゃって、何も操作できない・・・
処理をとめることさえ出来ない(Xボタンが利かない)
っていうのは、問題なのだ
■後勝ち方式の誕生
この問題を回避するため、
・ログイン数が一定数を超えたら、古いものから順に、セッション強制開放し、
新しい人のログインを優先させる
という手法が出てきた。ここでは後勝ち手法と呼ぶ。
このとき、強制開放された処理は、セッションが開放されているので、戻ってきたときに
異常終了する
一見、この方法で、うまくいくように思う・・・
■後勝ち方式の問題点
しかし、実は問題があるケースがある。
この「セッションを強制開放させられる」先の処理が、
ビッグデータ検索等を行っていて、すぐに帰ってこない場合。
(→だから処理中になっていて、だから、後からログインしたいわけだ)
先の処理をキャンセルしなければ、あとの処理は投入しても、
とってもおそい(たぶん、先の処理が終わってから投入したほうが早い。
だけど、先の処理の終わりを待てないから、今投入したんだ!)
このとき、1つ1つのサーブレットのインスタンスから直接、処理を
呼び出しているのなら、The Endだが、普通こういうときは、
キューにいれている。したがって、キューをキャンセルしなければならない。
このことを意識して、コーディングしている場合は問題ないが、
意識していないと、
・先の強制開放する処理のセッションを開放する
→開放されたセッションは、 HttpSessionBindingListener のvalueUnbound で
キューをキャンセルに行く
・後のログインに対するセッションを確保して、かえる
とプログラムを書いてしまう。
こう書くと、キューをキャンセルにいって、失敗したとき(あるいはなかなかキャンセル
出来なかったとき)、結局、あとでログインした人は、投入した処理は、待たされる。
■対策
制限人数(ライセンス数)を超えてログインしたら
「制限人数を超えています。先にログインした人を消しますか?」
ときいて、Noがクリックされたら、そこで終了(ログインできない)
YESがクリックされたら、
・消す人のビッグデータ検索等の処理がキュー入っていたら、それを中止する
・後処理して、セッション開放する
・これが成功したのを確認して、新しいログインに対して、セッションを発行する
→この間に失敗したり、CANCELされたら、新しいセッションが発行されず
「ふるい人のセッションも異常終了する(のを仕様とする)」
・古い人は、サーバーアクセスしたときに、異常終了通知を受け取る
とすればよい。
(後がち、先勝ちは、YES,NOのクリックでユーザーが選べる)