PoEAA ch17 Database Session State

PoEAAデザインパターン勉強メモ

出典: 


Database Session State

Stores session data as committed data in the database.

【補】語彙

  • レコードデータ

    • ビジネストランザクション完了後の完全なデータ
  • セッションデータ

    • ビジネストランザクション途中、システムトランザクション完了時にcommitされた中途データ

How It Works

  • リクエストのたび、必要なセッションデータをDBから取得

    • 検索用のセッションIDは最低限クライアント側で持つ必要がある
  • 取得するデータ

    • セッションデータ
    • 関連するレコードデータ
  • セッションデータとレコードデータは区別したい

    • 例: 注文

      • 日次売上に、未完の注文が反映されてほしくない
      • 完了した注文と区別したい
  • どう区別する

    • セッションデータ区別用のカラムを追加する

      • どんなの

        • isPending: boolean
        • sessionID

          • こちらのほうが良い
      • 侵略的なアプローチ

        • 既存のクエリへの変更が必要

          • WHERE sessionID IS NOT NULL句を追加する
          • 当該テーブルにアクセスする全アプリケーションに跳ねる
        • Viewで隠すことで回避できる

          • コストかかる
    • セッション管理用テーブルを分割する

      • PendingOrdersとか

        • 【補】リレーショナルモデル的にはこちらが正しいあり方だと思う

          • isPendingにNULLが入った時点で、第一正規形ですらないんですよ
      • 侵略的でない

        • 【補】もとのレコードデータのテーブルには一切手を加えない
      • O/Rマッピングコードに手を入れる必要がある

        • 【補】Data Mapperとか

          • OrderとOrderLineを取ってくるコード
            • PendingOrderとPendingOrderLineを取ってくるコード
      • レコードデータとセッションデータとで、データチェックのロジックは必ずしも一致しないことに留意する

        • 一貫性
        • バリデーション
      • sessionIDカラムの追加を除き、レコードデータのテーブルと同じテーブル定義にするとよい
  • セッションのキャンセル/離脱時に掃除が必要

    • キャンセル: セッションIDで検索して削除
    • 離脱: 古いやつを削除するdaemon

      • セッションテーブルは「最終更新時刻」を持っている必要がある
  • ビジネストランザクションのロールバックは複雑

    • 例: セッションの中で、既存の注文データに変更を加えようとし、やはり変更をキャンセルした場合
    • そもそもこの種のキャンセルを許さない案

      • レコードテーブルの既存の注文データを直接updateする
    • この種のキャンセルをサポートする場合

      • セッションテーブルを分割する場合

        1. 注文データをレコードテーブルからセッションテーブルに読み出す
        2. 変更する
        3. ビジネストランザクション完了時に、セッションテーブルからレコードテーブルに書き戻す
      • レコードテーブルにsessionIDカラムを追加する場合

        • セッションの最中は、同一のorder_idをもつ行が複数存在することになる

          • レコードデータ
          • セッションデータ
        • order_idはそれ単体でPKにできないことになる
        • 複雑
  • セッションテーブルを分割する場合は、Serialized LOBの適用も検討する

    • 【補】レコードデータのテーブルのテーブル定義を模さず、1つのLOBカラムとして突っ込む
    • もはやServer Session Stateパターン
  • セッションデータを区別しないという選択肢

    • 【補】前述の「ビジネストランザクションのロールバックをサポートしない」ケースはこれ
    • すべてがレコードデータ

      • 【補】システムトランザクションのcommit時に、直接レコードデータを更新する
    • 必ずしも選択可能な方法ではない

      • 可能でもやるべきではなかったり
    • Database Session Stateパターンの引き出しとして覚えておくとよい

When to Use It

  • Server Session State, Client Session Stateパターンとの比較
  • パフォーマンス

    • サーバをステートレスにできる

      • pooling、クラスタリング容易に
    • 代わりにリクエストごとにDBアクセスが発生する

      • 読み出しコストはキャッシュで減らせる
      • 書き込みコストは依然として残る
  • 実装面の労力

    • 大半はレコードデータとセッションデータとを区別するためのもの
    • リクエスト毎にレコードデータを直接更新していいなら、労力はほとんどない
  • Server Session State vs. Database Session State

    • クラスタリング・failoverをサポートする場合、Database Session Stateが素直

英語

  • invasive

    • invade派生
    • 侵略的