特集:クライアントステート管理、3つの手法Visual Studio Magazine(2/9 ページ)

» 2004年12月28日 10時30分 公開
[Matthew Gibbs, Rob Howard,FTPOnline]
<configuration>
<system.web>
<sessionState mode="InProc"
stateConnection
String="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="..."
cookieless="false"
timeout="20" />
</system.web>
</configuration>

 上記で「timeout」値には、セッションがタイムアウトと判断され、そのセッションが取り除かれるまでの時間を分単位で指定する。

 セッション状態には、時間切れをズラしていく機構(sliding expiration)が採用されている。言い換えれば、その項目がクライアントに要求されるごとにタイムアウトがリセットされるのだ。もし、timeout値で指定した時間に達する前にリクエストを1回でも発生させれば、理論上、セッションが無制限に活きているように見せることができる。

 インプロセスモードでは、任意のデータ型を保存できる。そして、新しいセッションが発生した場合には、グローバルセッションイベント「Session_OnStartイベント」が、セッションが破棄される時には、「Session_OnEndイベント」がそれぞれ発生する(訳注:それぞれSessionStateModuleクラスのStartイベントとEndイベントである)。これらのイベントのプログラムは、global.asaxファイルやHTTPモジュール中に記述できる。

 なお、Session_OnEndイベントは、使わないようにしよう。なぜならば、このイベントはインプロセスモードで作られたセッションの場合に限り呼び出され、アウトプロセスモードで作られたセッションでは、セッションが破棄されても発生しないからだ。

 ASP.NETのセッション状態は、「State Serverモード(StateServer)」と「SQL Serverモード(SQLServer)」という2つのアウトプロセスモードをサポートする。この2つは独自の構成設定を持っており、データの格納形式などそれぞれに特色がある。次の通りだ。

 State Serverモードは、中規模なWebアプリケーションでの利用が、SQL Serverモードでは、エンタープライズ環境や高トランザクションなWebアプリケーションでの利用が推奨される。

 プログラミングモデルが透過的であるということは重要だ。たとえば、セッション状態のモードを変更したとしても、セッション状態へのアクセス方法や利用方法を変更する必要はない。

 筆者の見解では、アウトプロセスモードでセッション状態を使う場合、SQL Serverモードを利用することを推奨する。なぜならばSQL Serverモードは、State Serverモードと同じ程度高速な上、データの管理面で優れているためだ。

 さらに、ASP.NETはSQL Serverにネイティブ通信でき(これは内部でSystem.Data.SqlClientライブラリを使うということを意味する)、また、データのフェイルオーバーをサポートするようにSQL Serverを構成することもできる。State Serverモードは、SQL Serverが存在しない場合に適切と言えよう。しかし、State Serverはレプリケーション、フェイルオーバー共にサポートしない。

アウトプロセスモードにおけるデータ型

 アウトプロセスモードを利用する場合、パフォーマンスを低下させるものとして挙げる問題のひとつが、格納対象となるデータのシリアライズとデシリアライズだ。ASP.NETでは、最適化された内部メソッドを用いることで、幾つかの基本型シリアライズやデシリアライズを行う。

 基本型としては、Int、Byte、Decimalのようなすべてのサイズの数値型、そして、String、TimeSpan、Guid、IntPtr、UintPtrのような幾つかの非整数型が挙げられる。これらの基本型ではない変数がセッション保存される場合には、ASP.NETでBinaryFormatterを用いてシリアライズやデシリアライズを行う。これは、内部メソッドに比べて処理が遅くなる。

 もしカスタムクラスを作っており、それをセッション状態に保存したいのであれば、対象とするクラスに[Serializable]メタデータ属性を付加するか、ISerializableインタフェースを実装しなければならない([Serializable]はC#のメタデータ属性で、<Serializable()>は、VB.NETのメタデータ属性)。

 SerializableAttributeクラスはSystem名前空間にあり、mscorlib.dllアセンブリで定義されている。ISerializableインタフェースは、mscorlib.dllアセンブリで定義、System.Runtime.Serialization名前空間にある(訳注:[Serializable]や<Serializable()>という記述によって)。クラスがSerializableAttributeという印が付けられていれば、クラスのすべてのpublicメンバは、シリアライズが試みられる。

 もしクラスがほかのオブジェクトへの参照を含んでいる場合には、それらのオブジェクトについてもSerializableAttributeという印を付けたり、ISerializableインタフェースを実装したりしなければならない。

 ISerializableインタフェースを実装すると、シリアライズやデシリアライズの振る舞いをより詳細に制御できるのだ(関連リンク:Serialize Objects in VB.NET)。

 性能を向上させるには、セッション状態に保存するデータを基本型だけで構成するのがよい。たとえば、「名前」と「住所」をセッション状態に保存する場合、2つのString型の変数を用いることができる。これは最も効率的な方法だ。

 もしくは、2つのString型のメンバを持つクラスを作り、そのインスタンス変数をセッション保存することもできる。しかし、これは効率的ではない。セッション状態には、基本型だけを格納し、複合型やカスタムクラスを格納しないようにしてほしい。

 基本型を格納することは、アウトプロセスのセッションにおいてシリアライズやデシリアライズによる処理速度の劣化を抑え、また、システムの複雑さを減少させる。State Serverアウトプロセスモードは、デフォルトの構成設定の変更だけでなく、実行中のWindows NTサービスにも依存する。

 次ページに挙げるコードは、State Serverモードの構成設定に必要なmachine.configファイルだ。

© Copyright 2001-2005 Fawcette Technical Publications

注目のテーマ