他からの読取りは許すが書込みを禁じる読取り用のロック。
共有ロック(読み取りロック、S(Shared)ロック)とは、他からの読み取りは許すが、書き込みは禁止する読み取り専用のロックのことです。複数のトランザクションが同じデータに同時に共有ロックをかけられます。
身近な例で考えると、図書館で1冊の本を複数人がのぞき込んで読むのに似ています。読むだけなら大勢で同時に見ても問題ありません。ただし誰かが「ページを書き換えたい(更新したい)」と言い出したら、読んでいる人がいる間は書き換えられません。
上のツールで▶ボタンを押すと、T1とT2が両方とも共有ロック(S)を取って同時に読み取り、書き込み要求は待たされる様子を確認できます。
共有ロックが「読み取りを並行できる」のは、読むだけならデータの中身を変えないので、何人で同時に読んでも結果が変わらないからです。みんなが同じ正しい値を見られます。
ロックが「両立できるか」は次のルールで決まります。
・共有ロック(S)+ 共有ロック(S):両立できる(同時に読める)
・共有ロック(S)+ 専有ロック(X):両立できない(書き込みは待つ)
・専有ロック(X)+ 何か:両立できない(書き込み中は誰も触れない)
この「両立できる組み合わせ」を整理した表をロックの両立性(適合性)と呼びます。読み取り同士だけが両立する、と覚えておけば十分です。
ロックには共有ロックのほかに専有ロック(書き込み用、X(eXclusive)ロック)があります。専有ロックは書き込みのためのもので、ほかの読み取りも書き込みもすべて禁止します。
| 項目 | 共有ロック(S) | 専有ロック(X) |
|---|---|---|
| 用途 | 読み取り | 書き込み(更新) |
| 同時に複数取れる | 取れる(共存OK) | 取れない(1つだけ) |
| 他の操作の許可 | 読み取りは許す | 読み取りも書き込みも禁止 |
ひとことで言えば、共有ロックは「みんなで読める」、専有ロックは「ひとりだけ書ける」という違いです。読むだけの処理は共有ロックで並行させ、更新する処理は専有ロックで独占させることで、安全さと処理効率を両立させています。
「あるロックとあるロックが同時に取れるか」を一覧にした表をロックの相性表(適合性マトリクス)といいます。表の見方は次のとおりです。
・共有(S) × 共有(S):両立できる。複数のトランザクションが同時に読み取れる。
・共有(S) × 専有(X):両立できない。誰かが読んでいる間は書き込みを待つ。
・専有(X) × 共有(S):両立できない。書き込み中は読み取りも待つ。
・専有(X) × 専有(X):両立できない。書き込みは同時に1つだけ。
結論を一言にまとめると、「読み取り同士(S+S)だけが両立し、書き込みが絡むと必ず待たされる」というルールです。なぜこのルールが必要かというと、書き込み中に他から触られると中途半端な値が広まってデータが壊れるからです。読むだけなら値は変わらないので何人いても構いません。
デッドロック(=死の膠着)とは、複数のトランザクションが互いに相手のロック解放を待ち続けて、永久に先へ進めなくなった状態です。共有ロックを使っていても引き起こされる可能性があります。
典型的なシナリオは次のとおりです。
・T1がデータAに共有ロック(S)を取得し、次にデータBへの書き込みを試みる。
・T2がデータBに共有ロック(S)を取得し、次にデータAへの書き込みを試みる。
・T1はデータBのSロックが外れるまで待つ。T2はデータAのSロックが外れるまで待つ。
・お互いが相手の解放を待っているため、どちらも永久に動けなくなる。
身近な例で考えると、狭い一本道で対向車が来て、お互いが「相手が引いてくれるまで待つ」と言い張っている状態に似ています。デッドロックが起きると、DBMSがどちらかを強制的にキャンセルして解消します。