InnoDBのネクストキーロックによるデッドロックの例
あまりMySQLのことは自信ないですが。
一見問題なさそうに見える操作でデッドロックしてしまうケースがあったので動画にしてみました。
SELECTしてみて「有ればUPDEATE、無ければINSERT」や、あるいは「有れば何もせず、無ければINSERT」を行ないたい場合に、SELECT FOR UPDATEして無ければINSERTとしてしまうと、動画の最初の例のようにデッドロックしちゃいます。存在しない行に対してSELECT FOR UPDATEするとちょっと広めに行ロックがかかってしまう感じでしょうか。
「有ればUPDATE、無ければINSERT」であれば、INSERT ... ON DUPLICATE KEY UPDATEを使うのが良さそう。「有れば何もせず、無ければINSERT」なら、いきなりINSERTしてみて一意制約違反ではじいてもらうのがいいのかな。
動画の2つめの例は、i = 100が存在するときに、WHERE i = 200 FOR UPDATEすると、100より大きい側はロックされるが100より小さい側はロックされないようだ、という実験。
動画の3つめの例は、存在する行に対してSELECT FOR UPDATEした場合の例です。
あと、存在しない行に対するDELETEやUPDATEでも、ちょっと広めの行ロックが発生するようです。
関連