Instiq
第4章 · トランザクションと同時実行制御·v1.0.0·更新 2026/7/10·読了目安 約16分

変更要約: 初版

4.2同時実行制御とロック

この節の要点

共有ロック(Sロック)専有ロック(Xロック)によるロック粒度の選択、そして直列化可能性を保証する2相ロックプロトコル(2PL)伸長相縮退相を学び、スループットと整合性のトレードオフから最適な同時実行制御方式を選ぶ判断力を養います。

複数の業務処理が同じ在庫テーブルや口座テーブルに同時にアクセスするシステムを設計するDBAにとって、「どの粒度で・どの種類のロックをかけるか」は、データ整合性とスループットを両立させる中心的な判断です。ロックを粗く・長く取れば整合性は堅牢になりますが同時実行性は下がり、細かく・短く取ればスループットは上がりますが整合性を損なうリスクが増します。この節では、同時実行制御の方式をどう設計すべきかを判断する視点を養います。

4.2.1共有ロックと専有ロック

  • 共有ロック(Sロック)=読み取り(SELECT)の際に取得するロックで、同じ資源に対し複数のトランザクションが同時にSロックを保持できる(読み取り同士は競合しない)。専有ロック(Xロック)=書き込み(UPDATE/INSERT/DELETE)の際に取得するロックで、他のいかなるロック(S/Xとも)とも同時に保持できない(排他的)。ある資源にXロックが掛かっていれば、他のトランザクションはSロックもXロックも取得できず待たされる。
  • ロック粒度=ロックをかける対象の範囲(行単位・ページ単位・表単位)。行ロックは粒度が細かく同時実行性が高いが、ロックの数が増え管理オーバーヘッドが大きい。表ロックは粒度が粗く管理は軽いが、表全体が対象のため同時実行性は低い。多くのRDBMSは行ロックが競合しそうな更新パターンを検出すると自動的に表ロックへロックエスカレーションする。

4.2.22相ロックプロトコルと直列化可能性

  • 2相ロックプロトコル(2PL)=各トランザクションのロック取得・解放を2つの相に分ける規則。伸長相(Growing Phase)では新たなロックの取得のみ許され解放は行わない。ひとたび1つでもロックを解放すると縮退相(Shrinking Phase)に入り、以後はロックの解放のみ許され新規のロック取得は一切できない——一度縮退相に入ったら伸長相には戻れないのが規則の核心。
  • 2PLに従う全てのトランザクションのスケジュールは直列化可能(複数トランザクションを並行実行した結果が、それらを何らかの順序で1つずつ実行した結果と等価になる)であることが理論的に保証される。ただし2PLだけではデッドロック(次節で詳述)は防げない点に注意——直列化可能性の保証とデッドロックフリーは別の性質である。実務では全ロックをCOMMIT/ROLLBACK時に一括解放する厳格な2相ロック(Strict 2PL)が広く使われ、これにより連鎖的なロールバック(カスケーディングアボート)も防げる。
試験ポイント

「Sロック=読み取り用・複数Txで共有可」「Xロック=書き込み用・他のいかなるロックとも排他」「2PL伸長相=取得のみ」「2PL縮退相=解放のみ・伸長相には戻れない」「2PLは直列化可能性を保証するがデッドロックは防げない」が最頻出です。「2PLならデッドロックも起きない」という誤解に注意。

あるオンライン座席予約システムのDBAが、繁忙期のアクセス集中でスループットが低下している問題を調べているとします。調査の結果、座席の空き状況を照会するSELECT処理と、座席を確保するUPDATE処理が、同一の座席テーブル全体を対象にした表ロック(表単位の粒度)を取得していることが原因と判明します。ここで採るべき設計判断は、ロックの粒度を行ロック(座席1件単位)に細分化することです——同一の座席行を更新するトランザクション同士は引き続き排他されますが、異なる座席への照会・更新は互いに待たされなくなり、同時実行性が大幅に向上します。ただし、行ロックへの細分化だけでは直列化可能性は保証されないため、各トランザクションが2相ロックプロトコル(2PL)に従っているかを確認する必要があります——具体的には、座席の空き確認(Sロック取得)と確保(Xロック取得)を1つのトランザクション内で行い、ロックを取得しきるまで一切解放しない伸長相を経てから、COMMIT時に一括解放する厳格な2PLの実装になっているかを点検します。ここで陥りやすい誤りは、「ロックを早期に解放すればスループットが上がるはずだから、座席確保のUPDATE完了後すぐにロックを解放し、その後で在庫サマリの更新を別途行う」という設計です——一度ロックを解放して縮退相に入った後、同じトランザクション内で新たなロックを取得することは2PLの規則違反であり、直列化可能性が崩れて二重予約のような不整合を招くおそれがあります。

ロック種別/相挙動
共有ロック(S)読み取り用・複数Txで同時保持可
専有ロック(X)書き込み用・他のいかなるロックとも排他
2PL伸長相ロック取得のみ・解放不可
2PL縮退相ロック解放のみ・新規取得不可・伸長相へ戻れない
注意

ひっかけ: 「2相ロックプロトコルに従っていればデッドロックは発生しない」は誤りです——2PLが保証するのは直列化可能性であり、デッドロックフリーとは別の性質です(デッドロックは次節で扱う検出/回避策が必要)。また「トランザクション内でロックを一度解放した後に別の新しいロックを取得してもよい」も誤り=縮退相に入った後の新規ロック取得は2PL違反で、直列化可能性が崩れます。

共有/専有ロック・2相ロックの図。
並行実行を正しく直列化

4.2.3この節のまとめ

  • 共有ロック(S)は読み取り用で共有可、専有ロック(X)は書き込み用で他の全ロックと排他
  • ロック粒度は行/ページ/表単位——細かいほど同時実行性が上がるが管理オーバーヘッドも増える
  • 2相ロック(2PL)は伸長相(取得のみ)→縮退相(解放のみ)で直列化可能性を保証するが、デッドロックは別途対処が必要

進捗の記録にはログインが必要です。

理解度チェック

(軽い確認用)

Q1. オンライン座席予約システムで、座席の空き照会と確保の両方が座席テーブル全体を対象にした表ロックを取得しており、繁忙期にスループットが低下している。この問題への最も適切な対処はどれか。

Q2. あるトランザクションが2相ロックプロトコル(2PL)に従って実装されている。座席の確保(Xロック取得)の直後にそのロックを解放し、その後同じトランザクション内で在庫サマリ更新のための新たなXロックを取得しようとした。この設計の問題点はどれか。

Q3. 複数のトランザクションが同一の顧客テーブルの異なる行を頻繁に更新するシステムで、行ロックを採用したところ、まれに更新頻度が突発的に高まった際にDBMSが自動的に表ロックへ切り替える挙動が観測された。この挙動の名称と目的として最も適切なものはどれか。

理解度を確認第4章「トランザクションと同時実行制御」の問題を解く

学習の記録を残しませんか

参考書はすべて無料で読めます。無料登録すると、問題集での演習・既読と進捗の記録・間違えた問題の復習・ハイライトが使えます。