自分の備忘のために。
ロックに関する思想の大枠
- 楽観ロック
- 例:プリミティブなREST API
- 「更新しようとするだけならいつでもOK」
- 「更新操作がぶち当たったら、早いもの勝ち若しくは遅いもの勝ち」
- 悲観ロック
- 「更新操作をする前にロック獲得を行う」
- 「ロック獲得が行えなかったら更新操作すら許さない」
- 「更新操作自体の失敗はないように制御する」
ロックに関する実装レイヤで考えること
特に悲観ロックでは以下の状態を持つ?
- 共有ロック状態
- 占有ロック状態
同時アクセスを考える帳票共有システムにおける排他
どこまで要求仕様に厳密性が含まれるかどうか
占有ロックを厳密に実装し、共有ロックの概念は排除、占有ロック状態のIN/OUTをトリガにして非占有者に対する更新通知を行う?
データに対して下記の2状態を管理する状態遷移モデルを定義する概念が良い?これだと共有ロックが要らない気がするから、なにか間違えているのかも。
- 誰も編集しておらず、常に最新のデータを持てていると確信できる状態
- 誰かが編集しており、最新のデータを持てていないかもしれない状態
スケーラビリティと楽観/悲観ロック
REST APIを使ったシステム間連携を見据えた設計と、悲観ロックとは非常に相性が悪そう。
REST API部は楽観的ロックの思想でやり、システム間連携によるREST API callが発生した場合にはwebsocketなどを使った悲観ロックが破綻することを許容し、フェイルセーフのために楽観ロックが作動することを前提とした設計にすべきか。
この場合、悲観ロックが破綻した時点で、例えばレコードの編集中であっても「データレコードXXXがユーザYYYにより意図せず変更されました。最新データをロードして続行しますか?それともロードせずに編集を続けますか?」みたいに聞く選択肢があるかもしれない。
若しくは悲観ロックは諦めてしまう決定も必要かもしれない。
この場合、レコードを保存する時に「すでにレコードが更新されています。編集内容は破棄されます」みたいになってしまう。UXを考えた場合は避けるべきな気がする。
備考
「共有/占有ロックはデータに対する低レイヤの考え方で、最近のUI設計に対する考え方として不適」と考えていたが、取り入れることでかなり設計が楽になるかもしれない。