勉強日記

チラ裏

PoEAA ch17 Database Session State

martinfowler.com


Database Session State

Stores session data as committed data in the database.

【補】語彙

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パターン
  • セッションデータを区別しないという選択肢
    • 【補】前述の「ビジネストランザクションロールバックをサポートしない」ケースはこれ
    • すべてがレコードデータ
    • 必ずしも選択可能な方法ではない
      • 可能でもやるべきではなかったり
    • Database Session Stateパターンの引き出しとして覚えておくとよい

When to Use It

  • Server Session State, Client Session Stateパターンとの比較
  • パフォーマンス
    • サーバをステートレスにできる
    • 代わりにリクエストごとにDBアクセスが発生する
      • 読み出しコストはキャッシュで減らせる
      • 書き込みコストは依然として残る
  • 実装面の労力
    • 大半はレコードデータとセッションデータとを区別するためのもの
    • リクエスト毎にレコードデータを直接更新していいなら、労力はほとんどない
  • Server Session State vs. Database Session State

英語

  • invasive
    • invade派生
    • 侵略的