
きょうは「待つか、待たないか」をこちらで決める指定の話をします
データベースを触っていて、こうなったことはないでしょうか。
実行したのに、返ってこない。
エラーも出ない。
ただ、止まっている。
あれ、いちばん困るやつ……

あのとき、裏では「待たされて」います。
誰かが先に、その行を押さえているのです。
NOWAITは、その待ち方をこちらで決めるための指定です。
ここは、大人の学び直しでつまずきやすいところだと思っています。
学生時代の勉強は、正解を覚えるものでした。
ところがこの指定に、正解はありません。
待つのが正しいときもあれば、待たないのが正しいときもある。
決めるのは、自分の側の事情です。
なので、判断できる形にして置いていきます。
結論:NOWAITは「待たない」と宣言する指定
押さえたい行が、すでに他の人に押さえられていた。
そのとき、待たずにすぐエラーを返してもらう。
それだけです。
ただ、この「それだけ」が効くのは、止まったまま気づけないという事故がとても多いからです。
そもそも、何を待っているのか
更新のために行を読むとき、その行は押さえられます。
読んだ内容をもとに書き換えるので、その間に他の人に変えられては困るからです。
押さえは、確定するか取り消すまで続きます。
つまり、待たされている相手は機械ではありません。
まだ確定していない、どこかの誰かの作業です。
あ、だから終わりが読めないのか


そうなんです。相手が席を立っていたら、こちらは延々と待ち続けることになります
ここが誤解されやすい:待ち方の既定は製品で違います
「しばらく待って、駄目ならエラーになる」
そう思っている方が多いところです。
実際は、製品によってまるで違います。
- Oracle … 既定では、押さえが外れるまでいつまでも待ちます。時間で諦める仕組みは、既定では入っていません
- MySQL(InnoDB) … 既定で50秒待ち、そこで諦めてエラーを返します
同じことを書いても、片方は止まり続け、もう片方は勝手に諦めます。
「待つ」の既定が同じだと思い込むと、移行したとたんに動きが変わります。
ここは覚える価値があると思っています。
調べずに済ませると、原因の見えない停止として出てくるからです。
付けると、どう変わるのか
書き方は、末尾に足すだけです。
SELECT * FROM employees
WHERE employee_id = 123
FOR UPDATE NOWAIT;
この行が押さえられていたら、待たずにエラーが返ります。
Oracleなら、番号はORA-00054です。
止まらない。
そして「取れなかった」と分かる。
この2つが、同時に手に入ります。
エラーが増えるのは、失敗ではありません
付けると、当然ながらエラーの回数は増えます。
それって、悪くなってない?


そう見えますよね。でも、待っていた時間も同じだけ失敗していたんです。見えていなかっただけで
待っている間、その処理は何も進んでいません。
しかも、待っている側も別の何かを押さえたままです。
そこに次の人が並ぶ。
詰まりは、後ろへ伸びていきます。
NOWAITは、失敗を増やす指定ではありません。
隠れていた失敗を、その場で見えるようにする指定です。
ただし、見えるようにした以上は受け止める側が要ります。
少し間を置いて、もう一度試す。
記録を残す。
画面には「混み合っています」と出す。
ここを決めずに付けると、利用者にエラーがそのまま出ます。
選択肢は、2つではありません
「待つ」か「待たない」かの二択だと思われがちです。
実際には、Oracleの場合こう分かれます。
- 待たずに、すぐ諦める … NOWAIT
- 秒数を決めて待つ … WAIT に秒数を添える
- 押さえられている行は飛ばして、取れる行だけ処理する … SKIP LOCKED
3つ目は、順番待ちの列をさばく処理で効きます。
複数人で同じ待ち行列を処理するとき、取り合いになりません。
取れた人が、取れた分だけ進める形になります。
え、飛ばすっていう手があるんだ


知らないと、まず思いつかない選び方なんです。だから、選択肢の形で覚えておいてほしくて
どう決めればいいか
判断の軸は、ひとつだけで足ります。
「この処理は、待たされても構わないか」
人が画面の前で待っているなら、待たせてはいけません。
夜間にまとめて流す処理なら、待っても構いません。
速さの話ではなく、誰が待つのかの話です。
そこを決めれば、指定は自然に決まります。
この手の知識は、覚えるより「引き出せる」ほうが効きます
最後に、勉強のしかたの話を少しだけ。
こうした指定は、数えきれないほどあります。
全部を覚えるのは、現実的ではありません。
大人の学び直しで効くのは、「待ち方は自分で決められる」と知っていることのほうです。
知っていれば、詰まったときに調べにいけます。
知らなければ、止まったまま原因を探し続けます。
覚える量ではなく、引き出しの数を増やす。
そこが、社会に出てからの勉強の分かれ目だと思っています。
この考え方は、学び直しが必要な理由。成長の源泉はどこにあるかにまとめました。
同じ「順番で結果が変わる」話としては、SQLのWHEREとHAVINGは何が違うのかも合わせてどうぞ。
