サブクエリの使用が難しいのは今のDBでも当てはまるのかな?

http://d.hatena.ne.jp/masanobuimai/20090219#1235050397

これ大事なお話なのでデータベース扱う人は必ず読んでおくこと。


通常ライブラリやフレームワークの楽観的ロックといったら後者のほうを表すんだけれども、前者も一応原理的には楽観的ロック。トランザクションの範囲がものすごく広いってイメージですな。どちらかというと運用方針できまる(後述)。


楽観的ロックはその原理から悲観的ロックでWAITと同様のことをやろうとするとトランザクションにループ処理が必要になる。意外と面倒。

たぶんこのへんが一番厄介なのはサブクエリ。複数行の更新でパフォーマンス出すために使う場合は仕方がないけど、データ件数が限られているのがわかっている場合、単純なSQLを複数発行したほうがロック取得箇所がわかりやすいというメリットがあったりする。複雑なサブクエリ使いまくりなのはよろしいのだが、それぞれどのタイミングでロックがかかるか、どういうときデッドロックがかかりそうか、危険そうかなどを他人に説明できない場合そのSQLの使用は考えたほうが良いと思う。


ただ、アプリとしてどういう更新をするかといった場合、ここでいう前者の仕組みを使うことは普通にあるかと。でも、せっかく入力したのに「他人が先に入力したので更新できませんでした」、というのは納得いかないかと思われ。かといって差分を表示してどちらを優先するかというアプリはあまり見たことはないですなー。

そんなこともあって、強制上書きも多いです。自前で単純なSQLを発行する場合はすべてのフィールドを更新してしまうとかいうこともあるけど、例えばJavaの標準APIO/RマッピングであるJPAとか真っ当なやつを使えば、何も考えず更新したフィールドのみ上書きされるので、影響が少ない可能性もあったり。なかったり。

この辺はDBの排他制御のお話ではなく、アプリの作成方針、運用方針ですね。場合によっては同一アプリでも画面単位で更新方法が異なる場合もあるのであらかじめ決めておいたほうが良いです。というか、決めないと作成に入ることが出来ませんよね。


えーっと、論点がころころ変わって何が言いたいのか忘れた(^-^;

とりあえずサブクエリーは意外と危険というのはいまのDBでも通じるお話なのかどうかが気になった、という誰もが悩むお話かな。