- PR -

DB登録の不具合。

1
投稿者投稿内容
キヨ
ベテラン
会議室デビュー日: 2004/08/24
投稿数: 65
投稿日時: 2004-12-15 17:56
お世話になってます。
現在ASP.NETでWebアプリケーションの開発を行っています。

Session変数を使って値の受渡をやってまして、
Page_LoadでSessionの値を変数もしくは構造体に入れる。
Page_Unloadで変数もしくは構造体の値をSessionに入れるという方法でポストバックの
対応をやってます。

そこで質問ですが、
この前、システム運用中に出た障害なんですが、
Session変数から構造体に入れて
その構造体を使ってDB登録用のSQLを流している処理で、
データが違う項目に登録されたという現象が発生しました。
ロジックを見てもそのようなコーディングは組んでいません。
発生したのは1件のみで、あとは正常です。
そのデータを登録したユーザさんに詳細を聞いてみると、
登録ボタンを押した時、ブラウザが固まったと言ってました。

ブラウザが固まると言う事は、通信中のエラーもしくは負荷が高かったからだと
推測されます。
もし、同じような現象になった方がいましたら、
どのような対応をしましたか?
ご教授下さい。お願いします。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-12-15 22:11
引用:

キヨさんの書き込み (2004-12-15 17:56) より:

Session変数を使って値の受渡をやってまして、
Page_LoadでSessionの値を変数もしくは構造体に入れる。
Page_Unloadで変数もしくは構造体の値をSessionに入れるという方法でポストバックの
対応をやってます。


 もう組あがっていて、動いているシステムなんですよね。。。それに対してこんなことを言うのは気が引けるのですが、組み方を間違っていると思います。たぶん。。。

 Page_Unloadというのは、Page.Unloadイベントのイベントハンドラですよね。で、これって、いつ動くか、把握していますか?MSDNの「コントロール実行の有効期間」というトピックに表があるのですが、Unloadイベントは最後の最後に実行されます。この段階で『変数もしくは構造体の値をSessionに入れる』というのが、よくわかりません。このイベントは、実はいつ実行されるかわかりません。おそらく、Pageオブジェクトを作成するのはaspnet_wpでしょうから、これがレンダリングがすんでクライアントにレスポンスを送った直後にDisposeしているとは思います。が、DisposeしているからといってUnloadが同じ時期に動いているかというと、そうでもない可能性があると思います。

 なんか、「たまたまうまく動いている」システムのように思います。
_________________
キヨ
ベテラン
会議室デビュー日: 2004/08/24
投稿数: 65
投稿日時: 2004-12-16 02:22
ご返答ありがとうございます。

変数や構造体のデータは、ポストバックが走ると
クリアされますよね?
データを保持したい場合、どのようにやっているのでしょうか。

>Unloadイベントは最後の最後に実行されます。
>この段階で『変数もしくは構造体の値をSessionに入れる』というのが、
>よくわかりません。このイベントは、実はいつ実行されるかわかりません
たとえば、ボタンを押すと、
Page.Loadイベント⇒ボタンクリックイベント⇒Page.Unload
と走りますよね? この動きが変わるって事ですよね?
いままで、色々テストしてきたんですが、確認出来ませんでしたが。。

たまたま・・・ 気にかかります。。。
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2004-12-16 03:09
Session情報へのアクセスにPropertyを介すると、良いのかも。
sia
会議室デビュー日: 2004/12/16
投稿数: 4
お住まい・勤務地: 福岡県
投稿日時: 2004-12-16 14:14
ポストバック時のWeb フォーム ページの処理順序については

1.Page_initイベントが発生しページとコントロールのビューステートが復元される
2.Page_Loadイベントが発生
3.コントロールのイベントが発生
4.HTMLページの表示
5.ページの表示が完了後にPage_Unloadイベントが発生

「Web フォーム ページの処理」
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcon/html/vbconwebformspageprocessingstages.asp
のようですので、

Page_Unloadイベントでセッション変数の値を更新しているのでしたら
ページが表示されなかったとき(データ転送が途中で中断されたときなど)は
セッション変数更新されないでしょう。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-12-18 06:32
引用:

キヨさんの書き込み(2004-12-16 02:22)より:

変数や構造体のデータは、ポストバックが走ると
クリアされますよね?

たとえば、ボタンを押すと、
Page.Loadイベント⇒ボタンクリックイベント⇒Page.Unload
と走りますよね? この動きが変わるって事ですよね?


 ポストバックが発生しても、データはクリアされません。データがクリアされるのではなく、新しいオブジェクトが実行されている、というのがより正しいです。えっと、Windowsアプリケーションでたとえると、いったん終了して、もう一度起動した状態。

 Page.Unloadは必ず動作しますが、動作するのは、おそらく不定時です。Disposeメソッド内でSuppressFinalizeされていれば、Disposeのタイミングで動作すると思いますが、それを期待してコーディングするのもどうかと。
 ん〜と、これはですね、、、
コード:
ページ要求→ページがnewされる      ↓例外発生
         ↓          ↓
      ページ内の様々な処理    ↓
         ↓          ↓
      ページがレンダリングされる ↓
         ↓          ↓
ページ表示←レンダリング情報を返す   ←
         ↓
      ページ破棄(Disposeメソッド)
         ↓
      Unloadイベント


こんな感じだと思います。ここで、「レンダリング情報を返す」以降の順番はわかりません。わかっているのは、必ずページは破棄され、Unloadイベントが発生することだけです。私は、Unloadイベントはファイナライザ/デストラクタで発生すると解釈しています。
 Pageクラスは、IDisposeableインタフェイスを実装しているので、Disposeメソッドが呼ばれているのは、ほぼ間違いないでしょう。この中で、SuppressFinalizeされていれば、同じタイミングでUnloadイベントも発生すると思います。えっと、上で「ページは必ず破棄され」と書きながら、ここで「ほぼ間違いない」としているのは、コーディング上Disposeメソッドが呼ばれていなくても、ガベージコレクションされるときには呼ばれるからです。つまり、もし、レンダリング情報をクライアントに返した後、Disposeメソッドをコールしていないなら、Unloadイベントが発生するタイミングは全くの不明になります。これが「たまたま動いている」とした理由です。そんな不作法なことはしていないでしょうが、要求を処理したスレッドが中断されずに実行し続けている保証はないので、何らかのタイミングでUnloadイベントよりも先に、同じセッションからの次のリクエストが到着し、それが処理されることはあるかもしれません。

 なんにしても、「要らなくなったときに処理される箇所」で「要るもの」を扱うのはよくないと思います。レンダリングを行うとき、またはViewStateにセットするときには値は確定しているので、まとめて行うならこの時点の方が確実かと思います。

_________________
1

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