排他制御と競合状態

技術の仕組み | システム設計

← 技術の仕組み

「空きを確認してから予約を確定する」——この2動作のすき間に別の人が割り込むと、両方とも「空き」を見て両方が確定し、二重予約や在庫マイナスが起きます。これが競合状態(レースコンディション)。防ぐには、確認と更新を途中で割り込まれない一続きにする=排他制御(ロック)が必要です。

先に押さえる

問題は「同時に複数の処理が同じデータを触る」こと。片方が読んで判断している間に、もう片方が同じ値を読んで別の判断をする。判断のもとになった値が、確定する頃には古くなっている——ここが事故の芯です。

競合状態が起きる瞬間

12人が同時に「残り1席」を見る
利用者A残り1席を確認
利用者B同時に残り1席を確認
2両方が「空いている」と信じて確定する
データ(残席)
Aが確定 → 残り0
Bも(古い「残り1」を根拠に)確定 → 二重予約
結果定員超過・在庫マイナス確認〜確定のすき間が原因

Bの確定は「確認した時点では正しかった」。でも確定の瞬間には状況が変わっていた。確認と確定が離れているほど、このすき間に割り込まれやすくなります。

防ぎ方 ― 確認と更新を一続きにする

見抜きどころ

直し方は「もっと速くする」ではなく、確認から更新までを他者が割り込めない一続きにすることです。対象の行にロックをかけて、片方が終わるまでもう片方を待たせる/更新時に「読んだ時と値が変わっていないか」を条件にして変わっていたらやり直す。設問では「いつ・どのデータの競合か」「なぜ確認だけでは足りないか(=確定まで守る)」を問われます。

つまずきやすい

「入力チェックを足す」だけでは防げません。チェックのに割り込まれるからです。守るのはチェックそのものでなく、チェック〜確定の区間。また、ロックは必要な範囲・時間だけにしないと、今度は待ちが増えて処理が詰まります(かけ過ぎも設計ミス)。

起こり方と防ぎ方をひと目で

起こり方・リスク

  • 確認と更新の間に割り込まれる(確認した時と確定する時で状態が変わる)
  • 二重処理・在庫のマイナス・残高の不整合・二重購入などの実害
  • 入力チェックを足すだけでは防げない(チェックの後で割り込まれる)

効く対策

  • 確認〜確定を他者が割り込めない一続きに(対象の行にロック)
  • 更新時に「読んだ時と値が変わっていないか」を条件にして、変わっていたらやり直す
  • ロックは必要な範囲・時間だけ(かけ過ぎは待ち増加=性能劣化)

この仕組みを使う設問