ロック

といってもROCKじゃないぜLOCKだぜ!
RDBMSoracleを使っていて、あるプログラムからこんなSQLを発行しているところがある。

select * from A for update

複数のスレッドからこのSQLは実行されるんだけど、デッドロックっぽい現象が起こっていると報告があった。知らなかったんだけど、oracleではselectの順番はorder by句をつけない場合、保証されていないとの事。そうなんや〜。order by句って特定のカラムで並び替えたい時に使うのであって、何も指定しなかった時は何らかのルールに基づいてselectされているんやと思っていた。つまりorder by句を省略すると「order by 主キー」みたいなのが暗黙的に追加されているんだと思っていた。
極端な例として、一定量のデータがある状態で、

select * from A order by id asc for update

select * from A order by id desc for update

をほぼ同時にSQL Plusのようなツールを使って実行してみると確かに一方で

ORA-00060: リソース待機の間にデッドロックが検出されました。

と表示される。なお、一方が完全に終わった状態でもう一方が同じSQLを実行するとこれは単に実行待ちとなり、一方がrollbackかcommitを実行すると次の瞬間、結果が取得できる。
というわけで、

select * from A order by id desc for update

のようにfor updateを使う時はorder by句もあわせて使うようにしましょう。
・・・っていうのはあっているのかな(ちょっと自信なし)。