PoEAA ch16 Optimistic Offline Lock
【補】用語
- セッションとビジネストランザクションがほぼ同義扱い
Optimistic Offline Lock
Prevents conflicts between concurrent busines transactions by detecting a conflict and rolling back the transaction.
- ビジネストランザクションは複数のシステムトランザクションにわたることがしばしば
- 単一のシステムトランザクション境界の外に出ると、レコードデータの一貫性の担保はRDBMS任せとはいかなくなる
- lost update
- 複数のセッションから同一のデータを更新
- inconsistent read
- あるセッションがデータを変更しているとき別のセッションから読み出し
- lost update
- Optimistic Offline Lockによる解決
- Pessimistic Offline Lockとの比較
- Optimistic-は、「衝突可能性は低い」という過程に基づく
- 複数ユーザが同じデータを同時に触れるようにする
- VCSとかがこの類
- 複数ユーザが同じデータを同時に触れるようにする
- cf. Pessimistic-は「衝突可能性が高い」という過程に基づく
- 同じデータを同時に触れるのは1ユーザのみ
- Optimistic-は、「衝突可能性は低い」という過程に基づく
How It Works
- あるセッションがレコードデータを読み出して依頼、別のセッションが変更を加えていないことを検証してロックを取得する
- 実装方法
- 最もよくある方法: レコードにversionカラムを追加
- 流れ
- Optimistic Offline Lock取得時、version値が変わっていないことを検証
- 変わっていたらロック取得させない
- ロック取得して、レコード更新時にインクリメント
- Optimistic Offline Lock取得時、version値が変わっていないことを検証
- 1つのSQL文でversionのインクリメントとロック取得を同時に行える
-
WHERE version = :version
に対してSET version = :version + 1
- DELETE文でも同様
- 更新行数が返ってくるので、ロック取得判定に用いる
- 1: 成功、ロック取得
- 0: 失敗
- abort
- 衝突解消してリトライ
-
- ユーザーに更新失敗を通知するために、「誰が」「いつ」更新をかけたかの情報も保持するのは有用
- 「いつ」をバージョン番号の代わりに用いるのはNG
- 信頼がおけない
- とくに複数サーバが協調動作しているとき
- 信頼がおけない
- 「いつ」をバージョン番号の代わりに用いるのはNG
- 流れ
- 別解
- WHERE句で全フイールド見る
- メリ
- バージョンフィールド不要
- デメ
- UPDATE文が複雑に
- パフォーマンス問題
- インデックスうまく効かなかったりする
- メリ
- WHERE句で全フイールド見る
- 最もよくある方法: レコードにversionカラムを追加
- versionフィールドを持つ方法では、必ずしもinconsistent readを防げない
- 例: 料金の税計算が顧客住所に依存するケース
- 料金レコードのversionを検証することで、他のセッションにより変更されていないことを担保できる
- が、住所レコードが変更されると税計算ロジックが変わり、inconsistent readがおきる
- この例では、住所レコードのバージョンチェックも必要
- 例: 料金の税計算が顧客住所に依存するケース
- versionカラムを再読み込みしてconsistent readであることをチェックできるためには、トランザクション分離レベルがrepeatable read以上であること
- 【補】unrepeatable read以下だと、同じversionカラムを読んでいるのに、他のシステムトランザクションのcommitが反映されて値が変わってしまう
- 並列性の向上
- Coarse-Grained Lock
- オブジェクトをグループ化して、単一のロック対象として扱う
- ドメインを知ること
- 本当に衝突はおきるのか?
- 税計算にいつ時点の住所を使うの?
- 複数のセッションで同時にアイテム追加していいの?
- VCS: 身近なOptimistic Offline Lockの例
- VCSのアナロジー: ビジネスデータのマージ
- 衝突の早期検出
When to Use It
- 衝突可能性の低いときに適する
- 衝突したらrollbackか衝突解決
- 衝突可能性が高い場合はユーザビリティ悪い
- 衝突したらrollbackか衝突解決
- Pessimistic Offline Lockより実装が簡単
- Pessimistic Offline Lockとは相補的
- 衝突を最小限にしつつ並列アクセスを最大化するのが正しいアプローチ
- 【補】Optimistic/Pessimisticをうまく併用しろということか