FE EXAM

専有ロック(排他ロック)

他からの読取りも書込みも禁じる更新用のロック。

INTERACTIVE VISUALIZATION
専有(X)
共有(S)
待ち
フェーズ
idle
データのロック
なし
在庫数
120
シナリオ
ステップ1 / 6
STEP 1/6開始前 — 更新用のロック専有ロック(書き込み用ロック、排他ロックとも呼ぶ)は「使っている間、他からの読み取りも書き込みも一切させない」もっとも強いロックです。T1(=トランザクション1)が在庫数を更新したい状況から始めます。在庫数は120です。
トランザクションT1待機中T2待機中共有データ在庫数120
解説

📌
専有ロックとは

T1書T2待専有ロック更新は1人だけ・他は待ち

専有ロック(排他ロック、X(eXclusive)ロック)とは、他からの読み取りも書き込みもすべて禁止する、更新(書き込み)用のロックのことです。あるデータに専有ロックを掛けられるトランザクションは、同時に1つだけです。

身近な例で考えると、個室トイレを使うのに似ています。中に入って鍵をかければ、その間は誰も入れませんし、中をのぞくこともできません。1人が使い終わって鍵を開けるまで、次の人はずっと待つしかありません。

上のツールで▶ボタンを押すと、T1が専有ロック(X)を取って在庫数を更新する間、T2は読み取りすらできず待たされ、解放後に最新の値を読む様子を確認できます。

🔒
排他制御の仕組み

XSXX はどれとも両立しない(待ち)

専有ロックによる「他をすべて締め出す」制御を排他制御といいます。排他とは「他をしりぞけて独占する」という意味です。専有ロックは次のどのロックとも両立できません。
専有(X)+ 共有(S):両立できない(読み取りも待たせる)
専有(X)+ 専有(X):両立できない(書き込みは1人だけ)

なぜここまで厳しく締め出すのでしょうか。それは、更新の途中の中途半端な値を他から読まれると、矛盾したデータが広まってしまうからです。たとえば在庫を120から100に書き換える途中の不正な値(例: 一瞬だけ0)を読まれては困ります。専有ロックは更新が完全に終わるまでデータを丸ごと隠すことで、これを防ぎます。

⚖️
共有ロックとの違い

共有ロックと専有ロックは、目的も挙動も対照的です。共有ロックは「読み取り用」で複数人が同時に取れますが、専有ロックは「更新用」で1人しか取れません。

項目共有ロック(S)専有ロック(X)
用途読み取り書き込み(更新)
他の読み取り許す(同時に読める)禁止(待たせる)
他の書き込み禁止禁止
同時取得複数OK1つだけ

ひとことで言えば、共有ロックは「みんなで読める鍵」、専有ロックは「ひとりで独占する鍵」です。読むだけなら共有ロックで並行を許し、更新するときだけ専有ロックで完全に独占する、という使い分けによって、安全さと処理効率のバランスをとっています。

🗂️
ロックの相性表

共有(S)専有(X)共有(S)専有(X)○ 両立✕ 待ち✕ 待ち✕ 待ち行 = すでに掛かっているロック / 列 = 新たに掛けようとするロック

「あるロックとあるロックが同時に取れるか」を一覧にした表をロックの相性表(適合性マトリクス)といいます。専有ロックの視点から整理すると、次のとおりです。
共有(S) × 共有(S):唯一両立できる組み合わせ。読み取り同士は共存してよい。
共有(S) × 専有(X):待ち。誰かが読んでいる間は書き込めない。
専有(X) × 共有(S):待ち。書き込み中は読み取りも禁止。
専有(X) × 専有(X):待ち。書き込み同士は絶対に同時にできない。

この表から分かるのは、専有ロック(X)は何と組み合わせても待ちになるということです。書き込みは「完全に独占しないと安全でない」ので、どんな相手もブロックします。専有ロックが名前どおり「排他的に独占する」ロックである理由がここにあります。

⚠️
更新が失われる問題

時間 →T1読: 120書: 110T2読: 120書: 90T1の「−10」の書き込みがT2の書き込みで上書きされて消える

専有ロックがないと「更新の失われ問題」(ロストアップデート)が起きます。これは、2つのトランザクションが同時に同じデータを読んで書き込んだとき、一方の更新がもう一方に上書きされて消えてしまう問題です。

具体例で考えます。在庫数が120のとき:
・T1が120を読み、在庫を10個出庫するため「120 − 10 = 110」を書こうとする。
・T2も120を読み(T1がまだ書いていないため)、在庫を30個出庫するため「120 − 30 = 90」を書く。
・最終的に在庫は90になるが、T1の「−10」の操作が完全に消えてしまっている。本当は120 − 10 − 30 = 80になるべきだった。

専有ロックを使えば、T1が読んで書き終わるまでT2はデータに触れません。T2は必ずT1の書き込み後の値(110)を読むので、正しく110 − 30 = 80が得られます。これが「更新用には専有ロックが必要」な根本的な理由です。上のツールで▶を押すと、T1が書き込みを終えてからT2が正しい値を読む順序を確認できます。

練習問題

🎯
基本情報技術者 練習問題

Q1.専有ロックの説明として最も適切なものはどれか。
A.他からの読み取りは許すが、書き込みだけを禁止するロック
B.他からの読み取りも書き込みもすべて禁止する更新用のロック
C.複数のトランザクションが同時に取得できるロック
D.データを読むためだけに使うロック
Q2.あるデータに専有ロックが掛かっているとき、他のトランザクションの動作として正しいものはどれか。
A.読み取りはできるが書き込みはできない
B.読み取りも書き込みもできず、ロック解放まで待たされる
C.読み取りも書き込みも自由にできる
D.別の専有ロックを同時に取れる
Q3.専有ロックが更新時に必要な理由として正しいものはどれか。
A.更新を高速化するため
B.更新中の中途半端な値を他から読まれて不整合が起きるのを防ぐため
C.データを暗号化するため
D.複数人で同時に書き込めるようにするため

関連コンテンツ