- - PR -
ASP.NET セッション変数
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-09-07 10:48
NALさんや一郎さんが書かれているように、Module内で変数を定義すると それは静的変数になります。 ASP.NETで静的変数を使っている場合、複数のクライアントが同じ一つの 変数を利用することになります。 > SQL文 = "SELECT * FROM <テーブル名>" > SQL文 &= " WHERE ログインユーザ = " & HttpContext.Current.Session("<セッション変数名>").ToString この「SQL文」がModule内で定義された変数であった場合、上記の理由から 同時にAさんとBさんがアクセスすると、常に後からアクセスした人の 値が利用されることになります。 問題点は ・Moduleの特性をよく知らずにASP.NETで利用した。 ・同時に利用するということに対してテストが不十分だった。 ということになるかと思います。 で、対処法としては、Moduleを使わない、すくなくともModule内で 変数を使わない形にプログラムを修正しましょう、ということになるかと。 | ||||
|
投稿日時: 2005-09-07 23:35
多々ご指摘、アドバイスありがとうございます。
「SQL文」はModule内で定義された変数です。 よって、後からアクセスした人の結果が返ってくる という部分は納得できました。 私の理解不足かもしれませんが、一点確認させて下さい。 Module内で他人の結果が返ってきた後に、Module内では なくフォームのコードビハインド部分で <テキストボックス名>.Text = Session("<セッション変数名>").ToString としているのですが、そこでテキストボックスに「B」と入るのは なぜでしょうか? 自分自身で整理する意味を含めてまとめると、 @「A」でログイン ↓ Aしばらくは「A」のまま実行している ↓ Bある時Module内の関数を呼び出す ↓ Cその際に「B」と実行が重なる (「B」の方が微妙にタイミングが遅い) ↓ D「B」として関数を実行した結果が返ってくる ↓ Eテキストボックスにセッション変数の値をセットする (Module内ではない場所) ↓ Fテキストボックスに「B」と表示される B〜Eの部分を簡単にコードで書くと、 ・Webフォーム Public Class WebForm1 Inherits System.Web.UI.Page ・ ・ Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'B関数呼び出し Dim X As Integer = Y() 'Eテキストボックスにセッション変数をセット TextBox1.Text = Session("<セッション変数名>").ToString End Sub End Class ・Module Module Module1 Function Y() As Integer 'CD静的変数により「B」の結果が返る Dim SQL文 As String SQL文 = "SELECT * FROM <テーブル名>" SQL文 &= " WHERE ログインユーザ = " & HttpContext.Current.Session("<セッション変数名>").ToString ・ ・ End Function End Module このFで「B」と表示される結果が分からないのです。 Module内でセッション変数を使用した際に、 同時に中身まで変わってしまうということなのでしょうか…? (余談1) SQLインジェクションの問題とか、StringBuilderを使用した方が 速いとかいう点は承知しております。 このプログラムは私の消し去りたい過去の一部でして、 直したいとは思っているのですがなかなか時間がとれず…。 (余談2) 毎回返答が遅くなりまして申し訳ありません。 私の会社では、インターネット掲示板と名のつくモノには 一律書き込み禁止のブロックがかかっておりまして、 会社にいるうちは返答ができません。 ご容赦ください…。 | ||||
|
投稿日時: 2005-09-08 00:07
確認したいのですが、Module 内で Shared(static) なのはメンバ変数だけですよね?(すみません。VB にかなり疎いです)
どうも特に static な変数がないような…。コード上問題ないように見えますが…。 それとも他の所でやっちゃってますか? 確認方法としては、ユーザAの場合は、Eの直前に無限ループでとめてみて、そしてユーザBでログインしてみて下さい。 そして、Eでブレークポイントを張ってみて、デバッガで値を確認する、とかはどうでしょうか? | ||||
|
投稿日時: 2005-09-08 10:29
ですか... 憶測(&未検証)ですが... Module内でHttpContext.Currentしているところが怪しいですね。 Class化することはできないのですか? 若しくはApplication.Lockを使って同時に処理されないようにするとか #これははずしているかも _________________ ASP/ASP.NETだいすき。 ASP++ by Moo http://moo-asp.net/ 日記は ほぼ毎日更新中 http://d.hatena.ne.jp/aspx/ | ||||
|
投稿日時: 2005-09-08 10:33
これもしかして、1台のマシンからIEを2つ立ち上げてテストしてるって ことはないですか? この場合、IEの設定によっては同じセッションを利用してしまいます。 | ||||
|
投稿日時: 2005-09-08 10:37
提示されたプログラムをみる限りではSessionの中身を見てるだけですから 書き換わるはずはありませんよね。 この後にSessionの値を書き換えるような処理があるなら別ですが。 | ||||
|
投稿日時: 2005-09-08 10:59
実験してみました。
Module Module1 Function x() As String Return (HttpContext.Current.Session.SessionID.ToString) End Function End Module
として1秒間に500リクエスト(セッションIDはすべて別)の 負荷試験してみましたが、問題なかったですね。 原因はほかのところにあるのでしょうか... _________________ ASP/ASP.NETだいすき。 ASP++ by Moo http://moo-asp.net/ 日記は ほぼ毎日更新中 http://d.hatena.ne.jp/aspx/ | ||||
|
投稿日時: 2005-09-08 23:23
さまざまご意見ありがとうございます。
セッション変数に値をセットするのはログイン直後の1回のみで、 以後はその部分を通りません。 これについては何度も確認しましたし、その部分にブレークポイントを つけていろいろ動かしたりもしたので、やはり意図的に上書きしている ような事はないはずです。 (静的変数により上書きされているなら、それは意図的ではないという事で…) また、この件はお客様からの報告により発覚したのですが、 私自身は現象を目の当たりにした事はありません。 再現しようと、アドバイス頂いたようにブレークポイントをつけたり、 複数台のPCで同時に動かしたりしたのですが、今までのところ再現できて おりません。 容易に再現できるならば、話はもっと簡単だと思うのですが…。 ちなみに、そのお客様が遭遇した際は、遠く離れた営業所のユーザIDに 突然変わってしまったそうです。 Module内で宣言した変数を使用しないように修正して、 様子を見てみるしかないでしょうか…。 |