データベーススペシャリスト 2024年 午前2 問14
問題文
トランザクションPが資源Xの値を4から5に更新した後にトランザクションQが開始し、Pがコミットする前にQが資源Xを参照しようとした。Qの挙動のa, bに入れる字句の組みはどれか。ただし、隔離性水準はREAD COMMITTEDとする。
〔Qの挙動〕
同時実行制御が単版2相ロッキングプロトコルの場合Qは(a)、多版同時実行制御(MVCC)の場合Qは(b)。

選択肢
ア:(正解)
イ:
ウ:
エ:
🔒 解説は解答すると表示されます
ロックとMVCCの読み取り挙動【午前2解説】
正解の理由
同時実行制御が単版2相ロッキング(単版2PL)の場合、Pが資源Xを更新している間はPが排他ロックを保持しているため、QがXを参照しようとするとPのコミット(=ロック解放)を待たされ、その後で更新後の値5を取得します。一方、多版同時実行制御(MVCC)で隔離レベルがREAD COMMITTEDのときは、Qは「最新のコミット済みバージョン」を返す方式のため、Pがまだコミットしていなければ古い値4が見え、Pのコミットを待つ必要はありません。以上より選択肢はアに一致します。
解法ステップ
- 同時実行制御方式を確認する(単版2相ロック vs MVCC)。
- 単版2相ロックの挙動を考える:
- 更新中の資源には排他ロックがかかる → 他トランザクションの読み取りはロック解放まで待機する。
- Pがコミット後にロック解放 → Qは値5を取得。
- MVCC(READ COMMITTED)の挙動を考える:
- READ COMMITTEDでは「各ステートメント実行時点での最新コミット版」を返す方式が一般的 → Pが未コミットなら古いコミット値(4)を返す。
- よって待機不要で値4を取得。
- 各選択肢の文言と照合して正しい組合せを選ぶ。
選択肢別の誤答解説
- イ(a: 待機して5、b: 待機せず5)
誤り。MVCC(READ COMMITTED)は未コミットの変更を他トランザクションに見せないため、Pの未コミット更新を即座にQが見て5を得ることはない。したがって連続して5を見られるという記述は間違い。 - ウ(a: 待機せず4、b: 待機せず5)
誤り。単版2PLではPの排他ロックが残っているかぎりQは待機する必要があるため、「待機せず4を得る」はありえない。またMVCCで未コミットの5を返すこともない。 - エ(a: 待機せず5、b: 待機せず4)
誤り。単版2PLが「待機せず5を得る」ことはできない(未解放の排他ロックがあるため)。MVCC側の記述は正しいが、a列が不適切のため選択できない。
よくある誤解
- MVCCは常に「トランザクション開始時点のスナップショット」を参照すると考える誤解。
→ 隔離レベルによって挙動が異なる。READ COMMITTEDでは通常「ステートメント実行時点の最新コミット版」を返し、REPEATABLE READやSnapshot隔離ではトランザクション開始時のスナップショットを参照する実装が多い。 - 排他ロック=書き込みのみ影響すると誤解する点。
→ 排他ロックを保持している資源は他トランザクションの読み取り要求(共有ロック取得)もブロックするため、読み取りが待たされる。 - MVCCなら常に「待たない」と考える誤解。
→ MVCCは読み取りでロックを取らないため待機しないことが多いが、書き込み競合や特定の実装(例えば明示的ロック要求)では待機や競合解決が発生する。
補足コラム
- 実装例:PostgreSQLのMVCCはREAD COMMITTEDで「各ステートメント開始時点のコミット済みスナップショット」(=ステートメント時点の最新コミット版)を使用します。InnoDB(MySQL)もREAD COMMITTEDでステートメント時点のコミット済みバージョンを返す挙動です。REPEATABLE READではトランザクション開始時のスナップショットを使い、同一トランザクション内で読み取り結果が固定されます。
- 単版2相ロッキング(strict 2PL)は一般に直列化可能性を保証します。更新トランザクションがコミットするまではその変更は他トランザクションから見えない(=待機させられる)ため、非整合な読み取りを防げますが並行性は低下します。
FAQ
Q1. READ COMMITTEDのMVCCは必ずトランザクション開始時点のスナップショットを参照しますか?
A1. いいえ。READ COMMITTEDでは通常「ステートメント開始時点での最新コミット版」を参照します。トランザクション開始時スナップショットを使うのはREPEATABLE READやSnapshot隔離です。
A1. いいえ。READ COMMITTEDでは通常「ステートメント開始時点での最新コミット版」を参照します。トランザクション開始時スナップショットを使うのはREPEATABLE READやSnapshot隔離です。
Q2. Pがコミットを取り消した(ロールバックした)場合、Qはどうなる?
A2. 単版2PLでQが待っていた場合、Pがロールバックすれば更新は破棄され、Qは待ち解除後に元のコミット済み値(4)を見ることになります。MVCCでは当初から最新のコミット値(4)を返しているので影響はありません。
A2. 単版2PLでQが待っていた場合、Pがロールバックすれば更新は破棄され、Qは待ち解除後に元のコミット済み値(4)を見ることになります。MVCCでは当初から最新のコミット値(4)を返しているので影響はありません。
Q3. Qが読み取りではなく書き込みを試みたら?
A3. 書き込み競合は実装依存です。単版2PLでは書き込みは排他ロック取得を試み、競合があれば待機またはデッドロック検出でロールバックされることがあります。MVCCでは書き込み時にバージョン競合を検出して待機やエラーになるケースがあります(例:更新失敗やリトライ)。
A3. 書き込み競合は実装依存です。単版2PLでは書き込みは排他ロック取得を試み、競合があれば待機またはデッドロック検出でロールバックされることがあります。MVCCでは書き込み時にバージョン競合を検出して待機やエラーになるケースがあります(例:更新失敗やリトライ)。
関連キーワード: 2相ロッキング、多版同時実行制御(MVCC)、READ COMMITTED、排他ロック、コミット可視性、ステートメントスナップショット、リードコミット

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

