このページについて
mysql のロック周りをメインに勉強したことを書いておく。
内容
インデックス周り
インデックスのはたらきによって、テーブルアクセスしなくても良かった場合のことを、 カバリングインデックスと言います。
ロック周り
どれもトランザクション中のロック
a -> b -> c の並びがあったときにbをfor updateでとったとき bよりも前にある疑似レコードにかかるロックをinfimum、後ろにかかるロックをsupremumという 例えば、b 以降のデータのinsertを防ぎたいときはsupermumに対してロックがかかる
レコードロック
その名の通り対象レコードに変更がないようにロック
ギャップロック
インデックス <-> インデックスの区間内にかかるロック insert 時に行が被らなければトランザクションが効いていてもブロックはされない トランザクション中で存在しない行に対してUPDATEなどを実行すると、インデックスのスキマ全域に対してロックがかかります。
id 100, 110 の並びで、id=105を更新する(実際にはない) と100 ~ 110 の間にロックがかかってしまう
参考 インテンションロック
ネクストキーロック
対象インデックスの範囲のレコードとその手前のレコード間(ギャップ)を埋める区間に対してロックがかかる
仕様など
mysql は インデックスでないフィールドを指定するとテーブルロックになる
インデックスを貼らないとレコードロックにならない
その他
トランザクション内で複数のテーブルを操作するときはデッドロックや並行性による問題が発生しないかよく検討すること
デッドロックを避けるには操作対象を主キーで並び替えたあとに処理を実行するなどがある。これは、他の処理と競合したようなときに更新順序が一意になっていないことでお互いにリソース解放待ちにならないようにするため。アプリケーション側で面倒をみてやる。