- PR -

楽観的ロックの定義について

1
投稿者投稿内容
hatahata
会議室デビュー日: 2008/09/08
投稿数: 2
投稿日時: 2008-09-08 13:37
楽観的ロック、悲観的ロックについて調べているのですが、Web上では定義がまちまちなように感じられ、わからなくなってしまいましたので質問させてください。


Webシステムでの以下の内容を例とします。

1.最初の画面で現在情報をselect(for updateなし)で取得して画面表示します。
2.画面の情報をユーザが修正し、更新をクリックします。
3.システム内で以下の処理を行います。
 3−1.select for updateで現在のDB上のデータを取得
 3−2.最初の画面で取得したバージョン番号と3−1で取得したバージョン番号を比較
 3−3.問題なければupdate実行


質問
(1)この処理はどちらのポリシーでのロックに分類されるでしょうか?

  (迷っている点)
  この流れが「楽観的ロックの実装方法」と紹介しているサイトがありました。
  確かに画面レベルで考えると検索ではロックせず、更新時にロックを取っているので楽観的ロックと呼べるように思えます。

  ですが、select for updateでロックを取得しています。
  「検索時にロックを取得するのが悲観的ロック」という定義を見かけたので厳密にいうとこれは悲観的ロックなのかとも思えます。
  また、そもそもselect for updateは悲観的ロックの代表のように記述されているサイトもありました。

  「select for update」では「デッドロック」が発生する可能性があるのも気になっています。
  「楽観的ロックではデッドロックはない」と書いてあるサイトがあったので、これから考えると「楽観的ロック」ではないのかとも思えます。


(2)3の個所で以下のどちらかの実装をするのが一番楽観的ロックの定義に近いように思えるのですが合っていますでしょうか?
   ・select for update nowaitを使う
   ・update文のwhere句にバージョン番号を指定し、更新が0件だったらrollback


(3)楽観的ロック、悲観的ロックの正式な定義文書というものはあるでしょうか?

  できれば日本語で正式文書があるとありがたいです。


以上、よろしくお願いいたします。


[ メッセージ編集済み 編集者: hatahata 編集日時 2008-09-08 13:38 ]

[ メッセージ編集済み 編集者: hatahata 編集日時 2008-09-08 13:39 ]
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2008-09-08 23:23
引用:

hatahataさんの書き込み (2008-09-08 13:37) より:
1.最初の画面で現在情報をselect(for updateなし)で取得して画面表示します。


「最初の画面で現在情報をselect(for updateあり)で取得して画面表示します。」が悲観的ロックと認識しています。

公式文書ではないですが、下記も参考になるかと思います。
http://blogs.sqlpassj.org/akiraonishi/articles/5026.aspx
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2008-09-09 01:22
楽観的ロック、悲観的ロックはロック方法の概念の話であって実装方法の話ではありません。

次の単位で語れば、3番の処理でDB情報が書き変わっている可能性があるため楽観的ロックになります。
引用:

1.最初の画面で現在情報をselect(for updateなし)で取得して画面表示します。
2.画面の情報をユーザが修正し、更新をクリックします。
3.システム内で以下の処理を行います。
 3−1.select for updateで現在のDB上のデータを取得
 3−2.最初の画面で取得したバージョン番号と3−1で取得したバージョン番号を比較
 3−3.問題なければupdate実行



しかし次の単位で語れば、最初の3−1番でDB情報が書き変わる状態を阻止しているため悲観的ロックになります。
引用:

 3−1.select for updateで現在のDB上のデータを取得
 3−2.最初の画面で取得したバージョン番号と3−1で取得したバージョン番号を比較
 3−3.問題なければupdate実行



更に次の処理単位はシステム全体で排他制御をかけるため悲観的ロックになります。
引用:

0.システムログイン時に全テーブルに排他ロック
1.最初の画面で現在情報をselect(for updateなし)で取得して画面表示します。
2.画面の情報をユーザが修正し、更新をクリックします。
3.システム内で以下の処理を行います。
 3−1.select for updateで現在のDB上のデータを取得
 3−2.最初の画面で取得したバージョン番号と3−1で取得したバージョン番号を比較
 3−3.問題なければupdate実行



要は、評価する処理範囲や処理単位内において、データが書き変わる可能性があるか、変わらないように対処しているか評価すればいいでしょう。

また楽観的ロックはデッドロックにならないとは言えません。
私の知っているDBMS製品はUpdateやDelete文で対象レコードにロックを掛けるため、意図的にロック処理をせずともレコード操作の内容によってはデッドロックが発生します。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-09-09 06:24
引用:

hatahataさんの書き込み (2008-09-08 13:37) より:
(1)この処理はどちらのポリシーでのロックに分類されるでしょうか?

  (迷っている点)
  この流れが「楽観的ロックの実装方法」と紹介しているサイトがありました。
  確かに画面レベルで考えると検索ではロックせず、更新時にロックを取っているので楽観的ロックと呼べるように思えます。

  ですが、select for updateでロックを取得しています。


提示された例だと、アプリケーションレベルのロックと、DBMSレベルのロックが混在していると思います。
アプリケーションレベルでは楽観的であり、DBMSレベルでは悲観的でしょう。

引用:

hatahataさんの書き込み (2008-09-08 13:37) より:
  「select for update」では「デッドロック」が発生する可能性があるのも気になっています。
  「楽観的ロックではデッドロックはない」と書いてあるサイトがあったので、これから考えると「楽観的ロック」ではないのかとも思えます。


これも、アプリケーションレベルでは楽観的ですが、DBを触る部分は悲観的なので、DBのところでデッドロックが起きる可能性は、悲観的なものに関することが当てはまります。
もっとも「select for update」と「デッドロック」に直接の関係はないと思います。「select for update」のように制限を付ければ、それを実現するためにはデッドロックの可能性が高まるというだけのことです。
hatahata
会議室デビュー日: 2008/09/08
投稿数: 2
投稿日時: 2008-09-09 19:33
皆さん、ご回答ありがとうございます。
大変参考になりました。

まとめさせていただくと以下の内容と理解しました。

 1.処理範囲、処理単位やAPレベル/DBMSレベルなど、観点によって楽観、悲観は異なる
 2.楽観的ロックであってもデッドロックが発生する可能性がある
 3.デッドロックはDBMSなどでも発生する可能性があるため、別途調査・検討が必要


回答をいただいてみてから気づいたのですが、私が特に知りたかったのは2,3でした。
現在のシステムはアプリケーション視点での楽観的ロックを採用予定なのですが、楽観的ロックだからデッドロック対策は不要といえるのかどうか、という点が焦点でした。

結論として、デッドロックについては実装方法やDBMSも含め別途検討が必要ですね。


皆さん、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)