共有行ロックと排他行ロックの違い

select ... for update;
select ... lock in share mode;

の違いがよくわからなかった。

  • データを更新する時に必要なロックは、for update
  • データを参照する時に必要なロックは、share mode

と体感的に理解できるのだが、どちらのロックを取ったときも、他の誰もデータを更新、削除できない。
また、どちらのロックも、(for update していたら、他から参照できないのかと思いきや)他の誰からも参照は可能。

ん?となると、この2つのロック、何がどう違うの??

その答えは ここ に書いてあった。(リンク先はPostgresだが、MySQLでも同じこと)

共有ロックとは、排他ロック(更新、削除、FOR UPDATE)をブロックする/される一方、共有ロック同士では互いにブロックしないというものです。

なるほど、share mode はセマフォみたいなもので、for update はクリティカルセクションか。んで、これらのロックは排他的な関係になっている、と・・。

つまり、for update で取得したロックは、自分だけしかロックを持っていないことが保証されるけど、share mode で取得したロックは、他の人もロックしている可能性があるということですな。

なので、share mode でロックできたからといい気になって(?)それらのロックした行をupdate なり deleteなりしようとしても、他の誰かに share mode でロックされているかもしれず、その場合は update や delete がブロックされてしまう、ということになる。

これでようやく、更新するために行ロックする時は for update を使用しなければならない、ということが理解できた。
めでたしめでたし。