なっトク!

SQL--DBMSのnowaitオプションって何?

2023-06-12

たすく

きょうは「待つか、待たないか」をこちらで決める指定の話をします

データベースを触っていて、こうなったことはないでしょうか。

実行したのに、返ってこない。

エラーも出ない。

ただ、止まっている。

あれ、いちばん困るやつ……

あかり

あのとき、裏では「待たされて」います。

誰かが先に、その行を押さえているのです。

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は何が違うのかも合わせてどうぞ。

  • この記事を書いた人
  • 最新記事

花丸たすく

▸「思考タイプ診断」で、働き方をスマートに
▸ あなたの価値を、現実を変える力へ
▸ 「IT戦略×データ分析×プロジェクトマネジメント」の知見
▸ 京都大学卒業後、教育・情報サービス系JTCなどでDX推進・データ分析・人材開発に従事