Coarse-Grained Lock
Locks a set of related objects with a single lock.
-
オブジェクトはグループとして編集される
- 例: 顧客と住所
- グループを構成する1要素を編集する際には、グループ全体をロックするのが理にかなっている
-
各要素別々にロックを管理するのは多くの困難をともなう
-
全要素検索してロックしなければならない
- 「顧客と住所」くらいなら問題ないが、オブジェクトグラフが大きくなってくると困難
-
Optimistic Offline Lockの場合
-
ロックのために全要素読み込まないといけない
- レコードにバージョンが紐付いているため
- 読まなくてもよいレコードも読んでしまいい、パフォーマンスに悪影響
-
-
Pessimistic Offline Lockの場合
- 管理が大変
- ロックテーブルにアクセス集中し競合が発生する
-
-
Coarse-Grained Lockでは、単一のロックで多数のオブジェクトをロックする
- ロック操作の簡略化
- ロックのために全レコード読み込まなくて良い
How It Works
-
Optimistic Offline Lockの場合
-
shared lock
-
グループ内の全オブジェクトは同一のバージョンオブジェクトを参照するようにする
- 同じ値ではなく、同一のバージョンを参照
- 共通のバージョンをインクリメントすることで、グループ全体がロックされる
-
-
-
Pessimistic Offline Lockの場合
- なにがしかのlockable tokenをグループ内の全オブジェクトで共有
- Optimistic Offline Lockパターンの「共通のバージョン」はまさにlockable tokenとして利用できる
-
Evansの「Aggregate」
-
root
- オブジェクトグラフのroot
-
boundary
- Aggregateに含まれるオブジェクトと外との境界
- boundary内部のオブジェクトには、root経由でのみアクセスできる
- rootをロックすることで、Aggregateを構成する全オブジェクトをロックしたことにする
-
Aggregateを構成する各オブジェクトからrootへのアクセスはどうする
- rootへの直接参照を保持する
-
親をrootまでたどる
-
オブジェクトグラフが巨大な場合、パフォーマンスに悪影響
-
Lazy Loadの併用
- 親オブジェクトを完全にロードしなくてもよいよう
- 無限ループ回避
-
Lazy Loadの問題
-
Inconsistent Readのおそれ
- 別々のシステムトランザクションでデータ読み取りが行われるため
-
-
-
-
実装の選定
-
root lock
- rootのみロックする
-
メリデメ
-
メリ
- root以外、バージョンテーブルとのjoin不要
-
デメ
-
rootまで親オブジェクトをたどる際に読み込み負荷がある
- Lazy Loadで回避できるが、Inconsistent Readがおきる
-
-
-
shared lock (Optimistic Offline Lock)
- Aggregateを構成する任意のオブジェクトをロックすると、root含め全オブジェクトがロックされる
-
メリデメ
-
メリ
- rootまで親をたどらなくてよい
-
デメ
- ほぼすべてのSELECT文でバージョンテーブルとのjoinが必要
-
-
Pessimistic Offline Lock
- ヘンな組み合わせ
-
-
When to Use It
-
機能要件
-
ビジネス要件
-
例: 「貸出」と「機材」
- あるユーザが貸出を編集しているとき、別のユーザが同時に機材を編集できてはいけない
-
-
-
非機能要件
-
パフォーマンス
- ロックの獲得・解放が低コストになる
-
-
オブジェクト間に不自然な関連を追加してしまうことに留意する
- 双方向参照
- rootへの直接参照