楽観ロック
optimistic locking
楽観的並行性制御, Optimistic Concurrency Control
複数人が同じリソースを同時に更新することはないだろうと、楽観視する
更新の競合が起きた場合は、最初のものを採用し、それ以降のものは破棄し、throwされる
version columnなど用意して運用する
数値
更新したらincrementする感じ
他の案
timestampでも良いが、例えば1秒未満の間に同時に更新が起きると問題になる
1秒よりもっと小さい単位でも同様
なのでtimestampは微妙
DBのデータを更新する処理の流れに沿うと、
①データの取得時にはロックをかけない
②更新する
③書き込む前にもう一度読み込む
①と内容が同じ場合
①~③の間に、他の人はそのデータを触っていない
問題ないので②を書き込む
①と内容が異なる場合
①~③の間に、他の人が同じデータを更新している
②を上書きすると整合性が壊れるので、②の結果を破棄する
errorを返す
#??
これってそもそも排他ロックではなくない?
ロックかけてないし
概念的にロックと同じ感じになっているだけ
どういうときに使う #??
失敗してもそこまで問題にならない場合
処理のやり直しが可能なとき
やり直しがあまり負担にならない時
複数人が同じリソースにアクセスする頻度が少ない時
嬉しい点
データの取得時に、待ちが発生しない
上の説明の①を任意のタイミングで行える
もし楽観ロックではないと、ロックがかかっているので他の人の作業が終わるまで取得できない
なので、そもそも「待っているプロセスなどに通知を送る」という概念がない
『On Optimistic Methods for Concurrency Control』
https://dl.acm.org/doi/10.1145/319566.319567
Optimistic Concurrency Controlの原典
https://the-weekly-paper.github.io/jekyll/update/2017/06/11/on-optimistic-concurrency-control.html
https://www.prisma.io/docs/guides/performance-and-optimization/prisma-client-transactions-guide#optimistic-concurrency-control
prismaのdocs
例が載ってる
https://help.sap.com/doc/saphelp_nw70/7.0.12/ja-JP/24/2649421c0bc753e10000000a1550b0/content.htm?no_cache=true
https://en.wikipedia.org/wiki/Optimistic_concurrency_control
https://qiita.com/kumagi/items/aad314574e1986f7243b